<?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; latchs</title>
	<atom:link href="https://blog.developpez.com/mikedavem/ptag/latchs/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>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>
