<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>David Barbarin &#187; locks</title>
	<atom:link href="https://blog.developpez.com/mikedavem/ptag/locks/feed" rel="self" type="application/rss+xml" />
	<link>https://blog.developpez.com/mikedavem</link>
	<description>MVP DataPlatform - MCM SQL Server</description>
	<lastBuildDate>Thu, 09 Sep 2021 21:19:50 +0000</lastBuildDate>
	<language>fr-FR</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=4.1.42</generator>
	<item>
		<title>Collaborative way and tooling to debug SQL Server blocked processes scenarios</title>
		<link>https://blog.developpez.com/mikedavem/p13186/devops/collaborative-way-and-tooling-to-debug-sql-server-blocked-processes-scenarios</link>
		<comments>https://blog.developpez.com/mikedavem/p13186/devops/collaborative-way-and-tooling-to-debug-sql-server-blocked-processes-scenarios#comments</comments>
		<pubDate>Thu, 30 Jan 2020 14:13:48 +0000</pubDate>
		<dc:creator><![CDATA[mikedavem]]></dc:creator>
				<category><![CDATA[DevOps]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[devops]]></category>
		<category><![CDATA[Extended events]]></category>
		<category><![CDATA[locks]]></category>
		<category><![CDATA[orphan transactions]]></category>
		<category><![CDATA[sp_WhoIsActive]]></category>
		<category><![CDATA[sqlserver]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/mikedavem/?p=1437</guid>
		<description><![CDATA[A quick blog post to show how helpful an extended event and few other tools can be to help fixing orphan transactions in a real use case scenario. I often gave training with customers about SQL Server performance and tools, &#8230; <a href="https://blog.developpez.com/mikedavem/p13186/devops/collaborative-way-and-tooling-to-debug-sql-server-blocked-processes-scenarios">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>A quick blog post to show how helpful an extended event and few other tools can be to help fixing orphan transactions in a real use case scenario. I often gave training with customers about SQL Server performance and tools, but I noticed how difficult it can be to explain the importance of a tool if you only explain theory without any illustration with a real customer case.<br />
Well, let’s start my own story that began a couple of days ago with an SQL alert to indicate a blocking scenario issue. Looking at our SQL dashboard (below), we were able to confirm quickly we are running into an annoying issue and it would be getting worse over if we do nothing.</p>
<p><span id="more-1437"></span></p>
<p><a href="http://blog.developpez.com/mikedavem/files/2020/01/153-1-SQL-dashboard.jpg"><img src="http://blog.developpez.com/mikedavem/files/2020/01/153-1-SQL-dashboard.jpg" alt="153 - 1 - SQL dashboard" width="1339" height="669" class="alignnone size-full wp-image-1438" /></a></p>
<p>&#8230;</p>
<p><a href="http://blog.developpez.com/mikedavem/files/2020/01/153-2-SQL-dashboard.jpg"><img src="http://blog.developpez.com/mikedavem/files/2020/01/153-2-SQL-dashboard.jpg" alt="153 - 2 - SQL dashboard" width="1874" height="663" class="alignnone size-full wp-image-1439" /></a></p>
<p>Let’s precise before continuing there are a plenty of tools to help digging into blocked processes scenarios and my intention is not to favor one specific tool over another one. So, in my case the first tool I used was the <a href="http://whoisactive.com/" rel="noopener" target="_blank">sp_WhoIsActive</a> procedure from Adam Machanic. One great feature of it is to get a comprehensive picture of what is happening on your system at the moment you’re executing the procedure.<br />
Here a sample of output I got. Let’s precise it doesn’t reflect exactly my context (which was a little more complex) but anyway my intention is not to focus on this specific part  </p>
<p><a href="http://blog.developpez.com/mikedavem/files/2020/01/153-3-sp_WhoIsActive.jpg"><img src="http://blog.developpez.com/mikedavem/files/2020/01/153-3-sp_WhoIsActive.jpg" alt="153 - 3 - sp_WhoIsActive" width="1339" height="328" class="alignnone size-full wp-image-1440" /></a></p>
<p>As you may see, I got quickly interesting information about the blocking leaders including session_id, the application name and the command executed as this moment. But the interesting part of this story was to get a request_id to NULL as well as a status value to SLEEPING. After some researches, having these values indicate likely that SQL Server has completed the command and the connection is waiting for the next command to come from the client. In addition, looking at the open_tran_count value (=1) confirmed the transaction was still opened. We started monitoring the transaction a couple of minutes to see if the application could manage to commit (or to rollback) the transaction but nothing happened. So, we had to kill the corresponding session to get back to a normal situation. A few minutes later, the situation came back with the same pattern and we applied the same temporary fix (KILL session).<br />
The next step consisted in discussing with the DEV team to fix this annoying issue once and for all. We managed to reproduce this scenario in DEV environment, but it was not clear what happened exactly inside the application because we got not specific errors even when looking at the tracing infrastructure. To help the DEV team investigating the issue, we decided to create a special extended event session that both monitor all activity scoped to the concerned application and the transactions that remain open during the tracing timeframe. Events will be easily correlated relying on causality tracking capabilities of extended events.  </p>
<p>So, the extended event session used two targets including the Event File and Histogram. Respectively, the first one was intended to write workload activity into a file on disk and the second one aimed identifying quickly opened transactions.</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;height:450px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">CREATE EVENT SESSION [OrphanedTransactionHunter] ON SERVER <br />
ADD EVENT sqlserver.database_transaction_begin(<br />
&nbsp; &nbsp; ACTION(sqlserver.database_id,sqlserver.session_id,sqlserver.tsql_stack)),<br />
ADD EVENT sqlserver.database_transaction_end(<br />
&nbsp; &nbsp; ACTION(sqlserver.database_id,sqlserver.session_id,sqlserver.tsql_stack)),<br />
ADD EVENT sqlserver.error_reported(<br />
&nbsp; &nbsp; ACTION(sqlserver.database_id,sqlserver.session_id,sqlserver.tsql_stack)),<br />
ADD EVENT sqlserver.module_end(<br />
&nbsp; &nbsp; ACTION(sqlserver.database_id,sqlserver.session_id,sqlserver.tsql_stack)),<br />
ADD EVENT sqlserver.module_start(<br />
&nbsp; &nbsp; ACTION(sqlserver.database_id,sqlserver.session_id,sqlserver.sql_text,sqlserver.tsql_stack)),<br />
ADD EVENT sqlserver.rpc_completed(<br />
&nbsp; &nbsp; ACTION(sqlserver.database_id,sqlserver.session_id,sqlserver.tsql_stack)),<br />
ADD EVENT sqlserver.rpc_starting(<br />
&nbsp; &nbsp; ACTION(sqlserver.database_id,sqlserver.session_id,sqlserver.sql_text,sqlserver.tsql_stack)),<br />
ADD EVENT sqlserver.sp_statement_completed(<br />
&nbsp; &nbsp; ACTION(sqlserver.database_id,sqlserver.session_id,sqlserver.tsql_stack)),<br />
ADD EVENT sqlserver.sp_statement_starting(<br />
&nbsp; &nbsp; ACTION(sqlserver.database_id,sqlserver.session_id,sqlserver.sql_text,sqlserver.tsql_stack)),<br />
ADD EVENT sqlserver.sql_statement_completed(<br />
&nbsp; &nbsp; ACTION(sqlserver.database_id,sqlserver.session_id,sqlserver.tsql_stack)),<br />
ADD EVENT sqlserver.sql_statement_starting(<br />
&nbsp; &nbsp; ACTION(sqlserver.database_id,sqlserver.session_id,sqlserver.sql_text,sqlserver.tsql_stack))<br />
ADD TARGET package0.event_file(SET filename=N'OrphanedTransactionHunter'),<br />
ADD TARGET package0.pair_matching(SET begin_event=N'sqlserver.database_transaction_begin',begin_matching_actions=N'sqlserver.session_id',end_event=N'sqlserver.database_transaction_end',end_matching_actions=N'sqlserver.session_id',respond_to_memory_pressure=(1))<br />
WITH (MAX_MEMORY=4096 KB,EVENT_RETENTION_MODE=ALLOW_SINGLE_EVENT_LOSS,MAX_DISPATCH_LATENCY=5 SECONDS,MAX_EVENT_SIZE=0 KB,MEMORY_PARTITION_MODE=NONE,TRACK_CAUSALITY=ON,STARTUP_STATE=OFF)<br />
GO</div></div>
<p>The outputs were as follows:</p>
<p>&gt; Target histogram (with opened transactions)</p>
<p><a href="http://blog.developpez.com/mikedavem/files/2020/01/153-4-xe-event-histogram.jpg"><img src="http://blog.developpez.com/mikedavem/files/2020/01/153-4-xe-event-histogram.jpg" alt="153 - 4 - xe event histogram" width="1473" height="69" class="alignnone size-full wp-image-1441" /></a></p>
<p>The only transaction that remained opened during our test (just be careful other noisy records not relevant at the moment when you start the XE session) concerned the session_id = 873. The attach_activity_id, attach_activity_id_xfer and session column values were helpful here to correlate events recorded to the event file target. </p>
<p>&gt; Event File (Workload activity)</p>
<p>Here the events after applying a filter with above values. </p>
<p><a href="http://blog.developpez.com/mikedavem/files/2020/01/153-5-xe-event-file.jpg"><img src="http://blog.developpez.com/mikedavem/files/2020/01/153-5-xe-event-file.jpg" alt="153 - 5 - xe event file" width="1333" height="303" class="alignnone size-full wp-image-1442" /></a></p>
<p>We noticed the transaction with session_id = 873 was started but never ended. In addition, we were able to identify the sequence of code executed by the application (mainly based on prepared statement and stored procedures in our context).This information helps the DEV team to focus on the right portion of code to fix. Without getting into details, it was very interesting to see this root cause was a SQL statement and duplicate key issue not thrown and managed correctly by the application. I was just surprised the application didn’t catch any errors in a such case. We finally understood that prepared statements and stored procedure calls were done through the DButils class including the closeQuietly() method to close connections. Referring to the <a href="https://commons.apache.org/proper/commons-dbutils/apidocs/org/apache/commons/dbutils/DbUtils.html" rel="noopener" target="_blank">Apache documentation</a>, closeQuietly() was designed to hide SQL Exceptions when happen which definitely not help identifying easily the issue from an application side. Never mind, thanks to the collaboration with the DEV team we managed to get rid of this issue <img src="https://blog.developpez.com/mikedavem/wp-includes/images/smilies/icon_smile.gif" alt=":)" class="wp-smiley" /></p>
<p>David Barbarin </p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>SQL Saturday 510 – Locks, latches et spinlocks – Les slides</title>
		<link>https://blog.developpez.com/mikedavem/p13075/evenements/sql-saturday-510-locks-latches-et-spinlocks-les-slides</link>
		<comments>https://blog.developpez.com/mikedavem/p13075/evenements/sql-saturday-510-locks-latches-et-spinlocks-les-slides#comments</comments>
		<pubDate>Sat, 09 Jul 2016 08:23:52 +0000</pubDate>
		<dc:creator><![CDATA[mikedavem]]></dc:creator>
				<category><![CDATA[Evénements]]></category>
		<category><![CDATA[concurrence d'accès]]></category>
		<category><![CDATA[latch]]></category>
		<category><![CDATA[locks]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[spinlock]]></category>
		<category><![CDATA[SQLSaturday]]></category>
		<category><![CDATA[SQLSaturday 510]]></category>
		<category><![CDATA[verrouillage]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/mikedavem/?p=1244</guid>
		<description><![CDATA[Cette année les gens ont encore répondu présent au SQLSaturday à Paris qui devenu incontournable pour ceux qui aiment échanger autour de la donnée avec les produits Microsoft. Par ailleurs, le temps a plutôt été au rendez-vous cette année et &#8230; <a href="https://blog.developpez.com/mikedavem/p13075/evenements/sql-saturday-510-locks-latches-et-spinlocks-les-slides">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Cette année les gens ont encore répondu présent au SQLSaturday à Paris qui devenu incontournable pour ceux qui aiment échanger autour de la donnée avec les produits Microsoft. Par ailleurs, le temps a plutôt été au rendez-vous cette année et la vue depuis le 40ème étage de la tour Montparnasse est toujours aussi impressionnante.</p>
<p>Pour ma part, j’ai eu le plaisir d’animer une session en fin de journée sur la concurrence d’accès mais vu depuis SQL Server avec 3 principaux mécanismes utilisés comme les locks, latches et spinlocks.</p>
<p>&gt; <a href="http://blog.dbi-services.com/sql-saturday-510-locks-latches-et-spinlocks-les-slides/" target="_blank">Lire la suite</a></p>
<p>David Barbarin<br />
MVP &amp; MCM SQL Server</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Renouvellement MVP et prochain événement SQLSaturday à Paris</title>
		<link>https://blog.developpez.com/mikedavem/p13067/evenements/renouvellement-mvp-et-prochain-evenement-sqlsaturday-a-paris</link>
		<comments>https://blog.developpez.com/mikedavem/p13067/evenements/renouvellement-mvp-et-prochain-evenement-sqlsaturday-a-paris#comments</comments>
		<pubDate>Sat, 09 Jul 2016 07:25:51 +0000</pubDate>
		<dc:creator><![CDATA[mikedavem]]></dc:creator>
				<category><![CDATA[Evénements]]></category>
		<category><![CDATA[AlwaysOn]]></category>
		<category><![CDATA[groupe de disponibilités]]></category>
		<category><![CDATA[haute disponibilité]]></category>
		<category><![CDATA[latch]]></category>
		<category><![CDATA[locks]]></category>
		<category><![CDATA[MVP]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[spinlock]]></category>
		<category><![CDATA[SQLSaturday]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/mikedavem/?p=1216</guid>
		<description><![CDATA[1er avril 2016, renouvellement MVP Data Plateform effectué (et pas de poisson d&#8217;avril). Une bonne nouvelle pour moi et un grand merci à Microsoft et à la communauté SQL Server. L&#8217;histoire continue donc et je voudrais partager avec vous les &#8230; <a href="https://blog.developpez.com/mikedavem/p13067/evenements/renouvellement-mvp-et-prochain-evenement-sqlsaturday-a-paris">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>1er avril 2016, renouvellement MVP Data Plateform effectué (et pas de poisson d&rsquo;avril). Une bonne nouvelle pour moi et un grand merci à Microsoft et à la communauté SQL Server.</p>
<p>L&rsquo;histoire continue donc et je voudrais partager avec vous les prochaines sessions que j&rsquo;aurais l&rsquo;occasion d&rsquo;animer à ce prochain événement qui se déroulera les 25 et 26 avril 2016.</p>
<p>&gt; <a href="http://blog.dbi-services.com/mvp-data-platform-renewed-and-next-sql-saturday-event-at-paris/" target="_blank">Lire la suite</a> (anglais)</p>
<p>David Barbarin<br />
MVP &amp; MCM SQL Server</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SET TRANSACTION ISOLATION LEVEL READ COMMITTED et NOLOCK = pas de verrous ?</title>
		<link>https://blog.developpez.com/mikedavem/p11994/sql-server-2005/set-transaction-isolation-level-unreadcommited-et-nolock-pas-de-verrous</link>
		<comments>https://blog.developpez.com/mikedavem/p11994/sql-server-2005/set-transaction-isolation-level-unreadcommited-et-nolock-pas-de-verrous#comments</comments>
		<pubDate>Mon, 27 May 2013 21:38:33 +0000</pubDate>
		<dc:creator><![CDATA[mikedavem]]></dc:creator>
				<category><![CDATA[SQL Server 2005]]></category>
		<category><![CDATA[SQL Server 2008]]></category>
		<category><![CDATA[SQL Server 2008 R2]]></category>
		<category><![CDATA[SQL Server 2012]]></category>
		<category><![CDATA[latchs]]></category>
		<category><![CDATA[locks]]></category>
		<category><![CDATA[SQL Server]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/mikedavem/?p=499</guid>
		<description><![CDATA[Chez un de mes clients on est venu me dire la chose suivante : visiblement lorsque j&#8217;utilise le hint NOLOCK ou un niveau de transaction READ UNCOMMITED lorsque j&#8217;exécute une requête je vois quand même des verrous posés sur mes &#8230; <a href="https://blog.developpez.com/mikedavem/p11994/sql-server-2005/set-transaction-isolation-level-unreadcommited-et-nolock-pas-de-verrous">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Chez un de mes clients on est venu me dire la chose suivante : visiblement lorsque j&rsquo;utilise le hint NOLOCK ou un niveau de transaction READ UNCOMMITED lorsque j&rsquo;exécute une requête je vois quand même des verrous posés sur mes tables alors que je croyais le contraire et du coup ma requête en lecture doit bloquer les mises à jour &#8230; A cela j&rsquo;ai répondu : la vérité est ailleurs <img class="wlEmoticon wlEmoticon-smile" style="border-top-style: none;border-left-style: none;border-bottom-style: none;border-right-style: none" alt="Sourire" src="http://blog.developpez.com/mikedavem/files/2013/05/wlEmoticon-smile.png" /></p>
<p>Plus sérieusement, la bonne question à se poser est la suivante : est-ce que le fait d&rsquo;utiliser un hint NOLOCK ou un niveau de transaction permettant la lecture sale veut dire que aucun verrou n&rsquo;est posé ? </p>
<p>&#160;</p>
<p>Pour répondre prenons un exemple simple avec une requête dans la base de données AdventureWorksDW2012 :</p>
<p><div class="codecolorer-container sql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span> &nbsp;<br />
<span style="color: #993333; font-weight: bold;">FROM</span> dbo<span style="color: #66cc66;">.</span>FactInternetSales <span style="color: #993333; font-weight: bold;">AS</span> f &nbsp; <br />
<span style="color: #993333; font-weight: bold;">CROSS</span> <span style="color: #993333; font-weight: bold;">JOIN</span> dbo<span style="color: #66cc66;">.</span>FactInternetSales <span style="color: #993333; font-weight: bold;">AS</span> f2</div></div>
</p>
<p>&#160;</p>
<p>Voyons les verrous posées par cette requête à l&rsquo;aide de la DMV sys.dm_tran_locks :</p>
<p><div class="codecolorer-container sql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333; font-weight: bold;">SELECT</span> &nbsp; <br />
&nbsp;resource_database_id<span style="color: #66cc66;">,</span> &nbsp; &nbsp; <br />
&nbsp;resource_type<span style="color: #66cc66;">,</span> &nbsp; <br />
&nbsp;resource_subtype<span style="color: #66cc66;">,</span> &nbsp; &nbsp;<br />
&nbsp;request_mode<span style="color: #66cc66;">,</span> &nbsp; <br />
&nbsp;request_type<span style="color: #66cc66;">,</span> &nbsp; &nbsp;<br />
&nbsp;request_status<span style="color: #66cc66;">,</span> &nbsp; &nbsp; <br />
&nbsp;request_owner_type &nbsp; &nbsp; <br />
<span style="color: #993333; font-weight: bold;">FROM</span> sys<span style="color: #66cc66;">.</span>dm_tran_locks &nbsp; &nbsp; <br />
<span style="color: #993333; font-weight: bold;">WHERE</span> request_session_id <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;session&quot;</span></div></div>
</p>
<p>&#8230;</p>
<p>&#160;</p>
<p><a href="http://blog.developpez.com/mikedavem/files/2013/05/icon_arrow4.gif"><img title="icon_arrow" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;margin: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="icon_arrow" src="http://blog.developpez.com/mikedavem/files/2013/05/icon_arrow_thumb4.gif" width="15" height="15" /></a> Avec un niveau d&rsquo;isolation de transaction en read committed (niveau d&rsquo;isolation par défaut) :</p>
<p><a href="http://blog.developpez.com/mikedavem/files/2013/05/image1.png"><img title="image" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="image" src="http://blog.developpez.com/mikedavem/files/2013/05/image_thumb1.png" width="784" height="82" /></a></p>
<p>&#160;</p>
<p><a href="http://blog.developpez.com/mikedavem/files/2013/05/icon_arrow5.gif"><img title="icon_arrow" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="icon_arrow" src="http://blog.developpez.com/mikedavem/files/2013/05/icon_arrow_thumb5.gif" width="15" height="15" /></a>&#160; Avec un niveau d&rsquo;isolation de transaction en read uncommitted :</p>
<p><a href="http://blog.developpez.com/mikedavem/files/2013/05/image2.png"><img title="image" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="image" src="http://blog.developpez.com/mikedavem/files/2013/05/image_thumb2.png" width="783" height="85" /></a></p>
<p>&#160;</p>
<p>On voit d&rsquo;abord que le niveau d&rsquo;isolation de transaction en mode read uncommitted ne veut pas dire qu&rsquo;il n&rsquo;existe plus de verrou. Le 1er verrou (de type SHARED_TRANSACTION_WORKSPACE) nous intéresse moins ici car c&rsquo;est un verrou posé lorsqu&rsquo;il existe une connexion sur une base de données (en l&rsquo;occurence database_id = 6 ici). Cela permet de protéger la base de données contre les suppressions accidentelles par exemple lorsqu&rsquo;il existe une connexion sur cette dernière. </p>
<p>Les verrous suivants sont plus intéressants dans notre cas. On voit que la différence notoire est qu&rsquo;il existe des verrous de type IS et type S dans un cas (read committed) et plus de verrou de ce type dans l&rsquo;autre cas&#160; (read uncommitted). Le niveau d&rsquo;isolation de transaction par défaut utilisé par SQL Server garantit une lecture propre des données c&rsquo;est la raison pour laquelle il existe des verrous de type S et IS à différents niveaux (OBJECT et PAGE) . Avec le niveau d&rsquo;isolation permettant de la lecture sale ces verrous n&rsquo;existent évidemment plus mais d&rsquo;autres verrous existent cependant comme celui que l&rsquo;on voit dans la dernière image : verrou de type Sch-S. Ce verrou protège la table contre les modifications pendant qu&rsquo;une lecture est effectuée même si celle-ci n&rsquo;est pas propre. </p>
<p>&#160;</p>
<p>Faisons le même test avec une table HEAP (sans index cluster) avec la requête suivante :</p>
<p><div class="codecolorer-container sql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span> &nbsp;<br />
<span style="color: #993333; font-weight: bold;">FROM</span> dbo<span style="color: #66cc66;">.</span>DatabaseLog <span style="color: #993333; font-weight: bold;">AS</span> f &nbsp; &nbsp; <br />
<span style="color: #993333; font-weight: bold;">CROSS</span> <span style="color: #993333; font-weight: bold;">JOIN</span> dbo<span style="color: #66cc66;">.</span>DatabaseLog <span style="color: #993333; font-weight: bold;">AS</span> f2</div></div>
</p>
<p>&#160;</p>
<p>&#8230; et voyons les verrous posées :</p>
<p><a href="http://blog.developpez.com/mikedavem/files/2013/05/icon_arrow6.gif"><img title="icon_arrow" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;margin: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="icon_arrow" src="http://blog.developpez.com/mikedavem/files/2013/05/icon_arrow_thumb6.gif" width="15" height="15" /></a> Avec un niveau d&rsquo;isolation de transaction en read committed (niveau d&rsquo;isolation par défaut) :</p>
<p><a href="http://blog.developpez.com/mikedavem/files/2013/05/image3.png"><img title="image" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="image" src="http://blog.developpez.com/mikedavem/files/2013/05/image_thumb3.png" width="781" height="111" /></a></p>
<p>&#160;</p>
<p><a href="http://blog.developpez.com/mikedavem/files/2013/05/icon_arrow7.gif"><img title="icon_arrow" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;margin: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="icon_arrow" src="http://blog.developpez.com/mikedavem/files/2013/05/icon_arrow_thumb7.gif" width="15" height="15" /></a>&#160; Avec un niveau d&rsquo;isolation de transaction en read uncommitted :</p>
<p><a href="http://blog.developpez.com/mikedavem/files/2013/05/image4.png"><img title="image" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="image" src="http://blog.developpez.com/mikedavem/files/2013/05/image_thumb4.png" width="778" height="84" /></a></p>
<p>&#160;</p>
<p>La aussi on peut voir qu&rsquo;avec les verrous de type S ne sont plus présents sur les objets de type PAGE ou OBJET avec un niveau d&rsquo;isolation de transaction en read uncommitted.&#160; On a néanmoins un type de verrou supplémentaire que l&rsquo;on n&rsquo;avait pas&#160; avec une table possédant un index cluster à la ligne 2 (resource_type = HOBT et resource_subtype = BULK_OPERATION). Ce type de verrou n&rsquo;est présent que sur les tables HEAP pour protéger les lectures contre les pages potentiellement mal formatés via des opérations BULK (merci à Paul Randal pour la précision).</p>
<p>&#160;</p>
<p>On vient donc de voir que la lecture sale sur SQL Server engendrait certains types de verrous. Cependant on peut pousser le raisonnement plus loin. Qui dit verrou veut dire aussi latch pour accéder aux structures physiques en mémoire &#8230; on peut essayer de voir si une requête avec un niveau d&rsquo;isolation en read uncommitted produit des latchs. Pour cela on peut utiliser la DMV sys.dm_os_waiting_tasks comme ceci :</p>
<p><div class="codecolorer-container sql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #808080; font-style: italic;">-- Création à la volée d'une table temporaire pour les tâches en attente &nbsp; &nbsp;</span><br />
<span style="color: #993333; font-weight: bold;">SELECT</span> TOP <span style="color: #cc66cc;">1</span> <span style="color: #66cc66;">*</span> &nbsp;<br />
<span style="color: #993333; font-weight: bold;">INTO</span> #waiting_tasks &nbsp; &nbsp; <br />
<span style="color: #993333; font-weight: bold;">FROM</span> sys<span style="color: #66cc66;">.</span>dm_os_waiting_tasks; &nbsp; &nbsp; <br />
<span style="color: #993333; font-weight: bold;">GO</span></div></div>
</p>
<p><div class="codecolorer-container sql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #808080; font-style: italic;">-- On vide la table avant le test &nbsp; </span><br />
<span style="color: #993333; font-weight: bold;">TRUNCATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> #waiting_tasks; &nbsp; &nbsp; <br />
<span style="color: #993333; font-weight: bold;">GO</span></div></div>
</p>
<p><div class="codecolorer-container sql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #808080; font-style: italic;">-- Récupération des tâches en attente générées par la requête de test &nbsp; &nbsp;</span><br />
WHILE <span style="color: #cc66cc;">1</span> <span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">1</span> &nbsp; &nbsp; <br />
<span style="color: #993333; font-weight: bold;">BEGIN</span> &nbsp; &nbsp; <br />
&nbsp;<span style="color: #993333; font-weight: bold;">INSERT</span> #waiting_tasks &nbsp; &nbsp; <br />
&nbsp;<span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span> &nbsp; &nbsp; <br />
&nbsp;<span style="color: #993333; font-weight: bold;">FROM</span> sys<span style="color: #66cc66;">.</span>dm_os_waiting_tasks &nbsp; &nbsp; <br />
&nbsp;<span style="color: #993333; font-weight: bold;">WHERE</span> <span style="color: #993333; font-weight: bold;">SESSION</span> <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;session&quot;</span> &nbsp; <br />
<span style="color: #993333; font-weight: bold;">END</span></div></div>
</p>
<p>&#160;</p>
<p>En parallèle la requête suivante est lancée :</p>
<p><div class="codecolorer-container sql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span> &nbsp; <br />
<span style="color: #993333; font-weight: bold;">FROM</span> dbo<span style="color: #66cc66;">.</span>DatabaseLog <span style="color: #993333; font-weight: bold;">AS</span> f &nbsp; <br />
<span style="color: #993333; font-weight: bold;">CROSS</span> <span style="color: #993333; font-weight: bold;">JOIN</span> dbo<span style="color: #66cc66;">.</span>DatabaseLog <span style="color: #993333; font-weight: bold;">AS</span> f2</div></div>
</p>
<p>&#160;</p>
<p>Après avoir lancé une des requêtes avec un niveau d&rsquo;isolation de transaction en read uncommitted on peut constater que cette dernière a effectivement générée des latchs de type SH dans notre cas :</p>
<p><a href="http://blog.developpez.com/mikedavem/files/2013/05/image5.png"><img title="image" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="image" src="http://blog.developpez.com/mikedavem/files/2013/05/image_thumb5.png" width="442" height="61" /></a></p>
<p>&#160;</p>
<p>On peut regarder à quel objet appartient la page 154 par exemple :</p>
<p><div class="codecolorer-container sql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">DBCC TRACEON<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">3604</span><span style="color: #66cc66;">&#41;</span>; &nbsp; <br />
<span style="color: #993333; font-weight: bold;">GO</span> &nbsp; &nbsp; <br />
<br />
DBCC PAGE<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">6</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">1</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">154</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">WITH</span> TABLERESULTS; &nbsp; &nbsp; <br />
<span style="color: #993333; font-weight: bold;">GO</span></div></div>
</p>
<p>&#160;</p>
<p><a href="http://blog.developpez.com/mikedavem/files/2013/05/image6.png"><img title="image" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="image" src="http://blog.developpez.com/mikedavem/files/2013/05/image_thumb6.png" width="689" height="270" /></a></p>
<p>&#8230;</p>
<p><a href="http://blog.developpez.com/mikedavem/files/2013/05/image7.png"><img title="image" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="image" src="http://blog.developpez.com/mikedavem/files/2013/05/image_thumb7.png" width="344" height="152" /></a></p>
<p>&#160;</p>
<p>Pour conclure l&rsquo;idée que l&rsquo;utilisation de la lecture sale avec SQL Server ne génère pas de verrous est faussée. Certains les verrous de type S pouvant gêner les écritures sont absents mais&#160; on a pu constater au cours de ce billet que d&rsquo;autres types de verrous étaient et bien présents ainsi que des latchs pouvant même aboutir à une potentielle contention !!</p>
<p>Bonne utilisation de lecture sale <img class="wlEmoticon wlEmoticon-smile" style="border-top-style: none;border-left-style: none;border-bottom-style: none;border-right-style: none" alt="Sourire" src="http://blog.developpez.com/mikedavem/files/2013/05/wlEmoticon-smile.png" />&#160;</p>
<p>David BARBARIN (Mikedavem)    <br />MVP SQL Server</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
