<?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>Arquivos dead lock - Diego Nogare</title>
	<atom:link href="https://diegonogare.net/tags/dead-lock/feed/" rel="self" type="application/rss+xml" />
	<link>https://diegonogare.net/tags/dead-lock/</link>
	<description>Consultor Executivo de IA &#38; ML</description>
	<lastBuildDate>Fri, 06 Nov 2020 14:34:37 +0000</lastBuildDate>
	<language>pt-BR</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>

<image>
	<url>https://i0.wp.com/diegonogare.net/wp-content/uploads/2025/06/cropped-cropped-DN-Black-300x300-1.png?fit=32%2C32&#038;ssl=1</url>
	<title>Arquivos dead lock - Diego Nogare</title>
	<link>https://diegonogare.net/tags/dead-lock/</link>
	<width>32</width>
	<height>32</height>
</image> 
<site xmlns="com-wordpress:feed-additions:1">247556142</site>	<item>
		<title>Usando o Transaction Isolation Level corretamente</title>
		<link>https://diegonogare.net/2013/01/transaction-isolation-level-voc-est-usando-certo/</link>
		
		<dc:creator><![CDATA[Diego Nogare]]></dc:creator>
		<pubDate>Mon, 14 Jan 2013 12:15:09 +0000</pubDate>
				<category><![CDATA[Artigo]]></category>
		<category><![CDATA[MSDN]]></category>
		<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[Tech Ed Brasil]]></category>
		<category><![CDATA[TechNet]]></category>
		<category><![CDATA[Virtual PASS BR]]></category>
		<category><![CDATA[dead lock]]></category>
		<category><![CDATA[isolation level]]></category>
		<category><![CDATA[lock]]></category>
		<category><![CDATA[sql server]]></category>
		<category><![CDATA[transacoes]]></category>
		<category><![CDATA[virtual pass br]]></category>
		<category><![CDATA[wait]]></category>
		<guid isPermaLink="false">http://diegonogare.net/?p=284</guid>

					<description><![CDATA[<p>Transaction Isolation Level você está usando certo? Fala galera, os Níveis de Isolamento (ou Transaction Isolation Level, do Inglês) não são apenas transações criadas para validar se um processamento gerou erro ou não, talvez você não esteja usando o Transaction Isolation Level corretamente. Vejo muita gente usando somente o BEGIN TRAN e COMMIT/ROLLBACK pensando que...</p>
<p>O post <a href="https://diegonogare.net/2013/01/transaction-isolation-level-voc-est-usando-certo/">Usando o Transaction Isolation Level corretamente</a> apareceu primeiro em <a href="https://diegonogare.net">Diego Nogare</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h1>Transaction Isolation Level</h1>
<h2>você está usando certo?</h2>
<p>Fala galera, os Níveis de Isolamento (ou <strong>Transaction Isolation Level</strong>, do Inglês) não são apenas transações criadas para validar se um processamento gerou erro ou não, talvez você não esteja usando o Transaction Isolation Level corretamente. Vejo muita gente usando somente o BEGIN TRAN e COMMIT/ROLLBACK pensando que estão usando transações de forma correta, afinal, se der algum problema durante o processamento ele pode voltar com um ROLLBACK e tudo estará tudo como antes.</p>
<p>Bom, por exemplo, olhar somente por essa ótica pode estar errado! Acima de tudo pelo fato do Isolation Level ter causas/efeitos mais profundos do que somente garantir que a transação que está rodando no momento dê erro ou não.</p>
<p>Vale lembrar que o SQL Server é um SGBD que implementa o conceito de <strong>ACID</strong> (<em>Atomicidade, Consistência, Isolamento e Durabilidade</em>) e os níveis de isolamento atuam diretamente neste conceito. Outra coisa que é bom lembrar é que os níveis de isolamento impactam diretamente na quantidade de <strong>LOCKs</strong> e <strong>WAITs</strong> gerados no SQL.</p>
<p>Por padrão, o SQL Server tem o Isolation Level configurado para <strong>READ COMMITED</strong>. Isso pode ser confirmado rodando esta linha de código abaixo, e encontrando o resultado de ISOLATION LEVEL.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="sql">DBCC USEROPTIONS</pre>
<h2>Usando o Transaction Isolation Level corretamente</h2>
<p>Para exemplificar estas explicações, e saber se está usando o Transaction Isolation Level corretamente, abra uma conexão com o SQL Server e execute o código abaixo. Ele irá criar um database e duas tabelas com alguns dados, onde serão explicados os tipos de isolamentos e de quebra um exemplo de dead lock.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="sql">CREATE DATABASE dbNogare
GO

USE dbNogare
GO

CREATE TABLE tbIsolationLevel
(Id INT IDENTITY,
 Col1 varchar(10),
 Col2 varchar(10),
 Col3 varchar(10)
)
GO

INSERT INTO tbIsolationLevel(Col1,Col2,Col3)
VALUES ('AAAAA','BBBBB','CCCCC')
GO 5

CREATE TABLE tbDeadlock (id INT)
GO

INSERT INTO tbDeadlock(ID)
VALUES (1), (2)

GO</pre>
<p>Quando alteramos o nivel de isolamento, ele é aplicado à conexão que o alterou. Se você abrir uma nova conexão com o SQL Server e verificar qual é o nivel de isolamento desta transação, você verá que voltou para o padrão. Read Committed.</p>
<h2>Transaction Isolation Level &#8211; Read Commited</h2>
<p>O <strong>READ COMMITTED</strong> nos garante uma leitura somente do que já está “comitado” no banco, isso é, garante que o dado que está sendo lido foi realmente escrito no banco e não é uma leitura suja ou fantasma, causado por alguma outra transação. Pelo fato dele só ler as informações realmente escritas no banco, se uma outra transação estiver trabalhando com a tabela que você quer ler, o SQL irá esperar a transação liberar a tabela para então fazer a leitura. Isso gera <strong>LOCK</strong> (<em>pela outra transação</em>) e <strong>WAIT</strong> (<em>pela sua</em>).</p>
<p>Para entender na prática esse tipo de isolamento, abra duas conexões diferentes com a tabela tbNogare. Execute o primeiro bloco de código em uma delas, contanto que o segundo bloco seja executado segunda conexão. Após iniciar a execução do primeiro, vá até a segunda conexão e execute em simultâneo, deixando ambas rodando. Você irá ver o SQL Server terminar de executar a primeira transação para então iniciar a segunda.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="sql">/*********  RODAR NA CONEXÃO 1 *********/
BEGIN TRAN
    UPDATE tbIsolationLevel set Col1 = 'DDDDD' where id = 1
    WAITFOR DELAY '00:00:10'
ROLLBACK TRAN

/*********  RODAR NA CONEXÃO 2 *********/
SET TRANSACTION ISOLATION LEVEL READ COMMITTED
SELECT * FROM tbIsolationLevel</pre>
<p>&nbsp;</p>
<h2>Transaction Isolation Level &#8211; Read Uncommited</h2>
<p>O <strong>READ UNCOMMITTED</strong> evita que o SQL Server dê um <strong>LOCK</strong> na tabela de leitura por causa de uma transação, isso faz com que também não gere um <strong>WAIT</strong> em outra transação. Porém, este processo permite uma <strong>leitura suja </strong>dos dados, entregando a informação “<em>errada</em>” em alguns cenários. Quando se utiliza este nível de isolamento, é possível ler os dados de uma tabela mesmo ela sendo utilizada dentro de uma transação longa que executa vários processos (<strong><em>INSERTS</em></strong>, <strong><em>UPDATES </em></strong>e <em><strong>DELETES</strong></em>). Estes passos intermediários que são executados antes do COMMIT no final, podem ser lidos e retornados. Quando isso acontece, chamamos de leitura suja (<strong>Dirty Read</strong>, do inglês).</p>
<p>Veja os códigos abaixo, e execute cada bloco simultaneamente em uma conexão diferente.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="sql">/*********  RODAR NA CONEXÃO 1 *********/
BEGIN TRAN
    UPDATE tbIsolationLevel set Col1 = 'DDDDD' where id = 1
    WAITFOR DELAY '00:00:10'
ROLLBACK TRAN

No código abaixo existem duas consultas. Ambas podem ler dados sujos, a primeira alterando o isolation level e a segundo consumindo dados com o hint WITH (NOLOCK). No final, o resultado de ambas serão os mesmos.

/*********  RODAR NA CONEXÃO 2 *********/
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
SELECT * FROM tbIsolationLevel

-- Usando o hint NOLOCK
SELECT * FROM tbIsolationLevel with (nolock)</pre>
<p>&nbsp;</p>
<h2>Transaction Isolation Level &#8211; Repeatable Read</h2>
<p>Já o <strong>REPEATABLE READ</strong> garante que a transação que leia uma tabela mais do que uma vez dentro desta mesma transação, possa fazer isso sem ler dados diferentes dos registros já encontrados da primeira vez. Nenhuma alteração (<strong>UPDATE</strong>) dos dados já lidos anteriormente serão modificados na leitura (são alterados na tabela), mas novos registros (<em>INSERT</em>) são retornados nesta segunda leitura.</p>
<p>Veja nos blocos de código abaixo este processo.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="sql">/********* RODAR NA CONEXÃO 1 *********/
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ

BEGIN TRAN
  SELECT * FROM tbIsolationLevel
  WAITFOR DELAY '00:00:10'
  SELECT * FROM tbIsolationLevel 
ROLLBACK TRAN</pre>
<p>&nbsp;</p>
<p>Veja o SQL Server gerando um <strong>WAIT</strong> para executar o <strong>UPDATE</strong>, mas não o gera quando roda o <strong>INSERT</strong>, ele simplesmente insere os dados.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="sql">/********* RODAR NA CONEXÃO 2 *********/
UPDATE tbIsolationLevel
 set Col1 = 'DDDDD'
 where id = 1

INSERT INTO tbIsolationLevel(Col1,Col2,Col3)
VALUES ('DDDDD','EEEEE','FFFFF')</pre>
<p>&nbsp;</p>
<h2>Transaction Isolation Level &#8211; Serializable</h2>
<p>Uma variação mais completa do REPEATABLE READ é o <strong>SERIALIZABLE</strong> que bloqueia qualquer modificação de dados nas colunas que são consultadas, independente da modificação ser um <strong>UPDATE</strong> ou um <strong>INSERT</strong>. Este nível de isolamento causa um <strong>LOCK</strong> na transação original e um <strong>WAIT</strong> na segunda transação tanto para o UPDATE quanto para INSERT.</p>
<p>Veja este processo nos códigos abaixo:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="sql">/*********  RODAR NA CONEXÃO 1 *********/
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRAN
    SELECT * FROM tbIsolationLevel
    WAITFOR DELAY '00:00:10'
    SELECT * FROM tbIsolationLevel
ROLLBACK TRAN




/*********  RODAR NA CONEXÃO 2 *********/
UPDATE tbIsolationLevel set Col1 = 'DDDDD' where id = 1

INSERT INTO tbIsolationLevel(Col1,Col2,Col3)
VALUES ('DDDDD','EEEEE','FFFFF')</pre>
<p>&nbsp;</p>
<h2>Transaction Isolation Level &#8211; Snapshot</h2>
<p>Uma alternativa para evitar <strong>LOCK</strong> e <strong>WAIT </strong>nas tabelas, e também garantir que os dados modificados sejam escritos e não tenha leitura suja é o <strong>SNAPSHOT</strong>. Ele permite tal ação porque ele copia os dados alterados para a tempdb, possibilitando ler os dados originais durante a transação, mesmo que eles sejam alterados. Quando uma transação tem um snapshot, ela coloca uma flag em todos os registros, para garantir que não foram alterados. Caso isso ocorra, ela altera a flag.</p>
<p>Veja na imagem abaixo a explicação deste processo.</p>
<p>Com o snapshot habilitado no banco, e setado na transação, ele lê os dados originais da tabela mesmo sofrendo modificações por outra transação.</p>
<p>Se os dados lidos não sofrerem nenhuma alteração, nada é escrito na tempDB.</p>
<p><a href="https://i0.wp.com/diegonogare.net/wp-content/uploads/2013/01/image-1.png?ssl=1"><img data-recalc-dims="1" fetchpriority="high" decoding="async" class="alignnone" style="background-image: none; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border: 0px;" title="image" src="https://i0.wp.com/diegonogare.net/wp-content/uploads/2013/01/image_thumb-1.png?resize=400%2C145&#038;ssl=1" alt="Tabela com dados preenchidos" width="400" height="145" border="0" /></a></p>
<p>Porém, se algum dado for modificado, o SQL Server continua lendo a tabela. Será lida a versão original do dado que foi modificado já que ele foi copiado para a TempDB. Na hora da leitura, o SQL se encarrega de ler a TempDB e recuperar o dado original.</p>
<p><a href="https://i0.wp.com/diegonogare.net/wp-content/uploads/2013/01/image1-1.png?ssl=1"><img data-recalc-dims="1" decoding="async" class="alignnone" style="background-image: none; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border: 0px;" title="image" src="https://i0.wp.com/diegonogare.net/wp-content/uploads/2013/01/image_thumb1-1.png?resize=400%2C142&#038;ssl=1" alt="Tabela com uma mudança de dados" width="400" height="142" border="0" /></a></p>
<p>Esta funcionalidade, por padrão, vem desabilitada do banco de dados, e para utilizar, é necessário habilitar fazendo uma alteração no database. No código abaixo, é possível ver essa alteração.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="sql">USE MASTER
GO

ALTER DATABASE dbNogare
SET ALLOW_SNAPSHOT_ISOLATION ON
GO

USE dbNogare
GO</pre>
<p>&nbsp;</p>
<p>Depois de habilitar o Snapshot Isolation Level no banco de dados, é hora de ver os blocos de códigos que possibilitam este nivel de isolamento.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="null">/*********  RODAR NA CONEXÃO 1 *********/
SET TRANSACTION ISOLATION LEVEL SNAPSHOT
BEGIN TRAN
    SELECT * FROM tbIsolationLevel
    WAITFOR DELAY '00:00:10'
    SELECT * FROM tbIsolationLevel
    UPDATE tbIsolationLevel set Col1 = 'XXXXX' where id = 2
    WAITFOR DELAY '00:00:10'
COMMIT TRAN




/*********  RODAR NA CONEXÃO 1 *********/
UPDATE tbIsolationLevel set Col1 = 'NNNNNN' where id = 1
SELECT * FROM tbIsolationLevel</pre>
<p>&nbsp;</p>
<h2>Problemas com Dead Lock</h2>
<p>Por fim, o <strong>DEAD LOCK</strong> também causa um pouco de confusão com sua execução. A causa de um DEAK LOCK é quando uma transação espera uma liberação para seguir em frente. Porém, a transação que está segurando o processo (causando <strong>LOCK</strong>) está esperando a primeira transação terminar de processar alguma coisa. A grosso modo, é <strong>A </strong>esperando o <strong>B </strong>terminar e o <strong>B</strong> esperando o <strong>A </strong>terminar. Eles ficariam um esperando o outro até alguém “desistir”. Para isso, o SQL Server escolhe uma <strong>vítima</strong> de acordo com o início do processo e o grau de severidade que aquele processo pode ter. Normalmente a transação que começou por ultimo é a vítima, se desligando do processo (o SQL faz isso automaticamente) e dá um <strong>rollback</strong> nas alterações. Isso faz com que a transação que ganhou o processo termine suas atividades.</p>
<p><a href="https://i0.wp.com/diegonogare.net/wp-content/uploads/2013/01/image2-1.png?ssl=1"><img data-recalc-dims="1" decoding="async" class="alignnone" style="background-image: none; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border: 0px;" title="image" src="https://i0.wp.com/diegonogare.net/wp-content/uploads/2013/01/image_thumb2-1.png?resize=400%2C142&#038;ssl=1" alt="Tabela com todos dados " width="400" height="142" border="0" /></a></p>
<p>Para ver isso através de código, execute os blocos abaixo.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="sql">/*********  RODAR NA CONEXÃO 1 *********/
SET TRANSACTION ISOLATION LEVEL READ COMMITTED
GO
BEGIN TRAN
    UPDATE tbDeadlock 
    SET id = 12
    WHERE id = 2
    WAITFOR DELAY '00:00:10'
    UPDATE tbDeadlock 
    SET id = 11
    WHERE id = 1
ROLLBACK TRAN




/*********  RODAR NA CONEXÃO 2 *********/
BEGIN TRAN
    UPDATE tbDeadlock 
    SET id = 11
    WHERE id = 1
    WAITFOR DELAY '00:00:10'
    UPDATE tbDeadlock 
    SET id = 12
    WHERE id = 2
ROLLBACK TRAN</pre>
<p>&nbsp;</p>
<p>Quando ocorre o dead lock, a mensagem de erro é assim:</p>
<p><span style="color: #ff0000;">Msg 1205, Level 13, State 45, Line 2 Transaction (Process ID 54) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.</span></p>
<p>&nbsp;</p>
<h2>Continue os estudos</h2>
<p>Se você deseja fazer o exame de certificação para SQL Server, é importante saber sobre esses assuntos. <a href="https://diegonogare.net/2012/12/dicas-para-o-exame-70-461-microsoft-querying-sql-server-2012/" target="_blank" rel="noopener noreferrer">Veja um exemplo de roteiro de estudos neste link</a>.</p>
<p>Bom galera, não existe uma formula mágica que diz qual nível de isolamento é melhor. Como visto nos exemplos, cada um deles tem seus pontos fortes para garantir integridade dos dados e fracos que geram demora nos processos. Contudo, é ideal que você entenda o que eles fazem e que possa aplicar cada um com seu cenário.</p>
<p>O post <a href="https://diegonogare.net/2013/01/transaction-isolation-level-voc-est-usando-certo/">Usando o Transaction Isolation Level corretamente</a> apareceu primeiro em <a href="https://diegonogare.net">Diego Nogare</a>.</p>
]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">2117</post-id>	</item>
	</channel>
</rss>
