Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Aplica-se a:SQL Server
Azure SQL Database
Azure SQL Managed Instance
Azure Synapse Analytics
Sistema de Plataforma de Análise (PDW)
Banco de dados SQL no Microsoft Fabric
Este artigo discute deadlocks no Mecanismo de Banco de Dados em profundidade. Os deadlocks são causados por bloqueios concorrentes e simultâneos no banco de dados, geralmente em transações de várias etapas. Para obter mais informações sobre transações e bloqueios, consulte o guia de bloqueio de transações e controle de versão de linha.
Para obter informações mais específicas sobre identificação e prevenção de deadlocks no Banco de Dados SQL do Azure e no Banco de Dados SQL no Fabric, consulte Analisar e evitar deadlocks no Banco de Dados SQL do Azure e no Banco de Dados SQL no Fabric.
Compreender impasses
Um deadlock acontece quando duas ou mais tarefas bloqueiam permanentemente uma à outra; uma tarefa está bloqueando um recurso que a outra tarefa está tentando bloquear. Por exemplo:
A transação A adquire um bloqueio compartilhado na linha 1.
A transação B adquire um bloqueio compartilhado na linha 2.
A transação A agora solicita um bloqueio exclusivo na linha 2 e é bloqueada até que a transação B termine e libere o bloqueio compartilhado existente na linha 2.
A transação B agora solicita um bloqueio exclusivo na linha 1 e é bloqueada até que a transação A termine e libere o bloqueio compartilhado existente na linha 1.
A transação A não pode terminar até que a transação B termine, mas a transação B está bloqueada pela transação A. Essa condição é também chamada de dependência cíclica: a transação A tem uma dependência da transação B, e a transação B fecha o círculo tendo uma dependência da transação A.
Ambas as transações em um deadlock esperam indefinidamente, a menos que o deadlock seja quebrado por um processo externo. O monitor de deadlock do Mecanismo de Banco de Dados verifica periodicamente as tarefas que estão em um deadlock. Se o monitor detectar uma dependência cíclica, ele escolhe uma das tarefas como vítima e termina sua transação com um erro. Isso permite que a outra tarefa complete sua transação. O aplicativo com a transação que terminou com um erro pode repetir a transação, a qual normalmente é concluída depois que a outra transação em deadlock é encerrada.
O deadlock é frequentemente confundido com bloqueio normal. Quando uma transação solicita um bloqueio em um recurso bloqueado por outra transação, a transação solicitante espera até que o bloqueio seja liberado. Por padrão, as transações no Mecanismo de Banco de Dados não têm tempo limite, a menos que LOCK_TIMEOUT esteja definida. A transação solicitante é bloqueada, não em deadlock, por que ela não fez nada para bloquear a transação que deve o bloqueio. Por fim, a transação proprietária será concluída e libera o bloqueio e a transação solicitante tem o bloqueio atribuído e prossegue. Deadlocks são resolvidos quase imediatamente, enquanto o bloqueio pode, em teoria, persistir indefinidamente. Os deadlocks às vezes são chamados de abraço mortal.
Um deadlock pode ocorrer em qualquer sistema com vários threads, não só em sistemas de gerenciamento de banco de dados relacional, e pode ocorrer para outros recursos, além de bloqueios de objetos em bancos de dados. Por exemplo, um thread em um sistema operacional de vários threads pode adquirir um ou mais recursos, como bloqueios de memória. Se o recurso que está sendo adquirido for atualmente propriedade de outro thread, o primeiro thread poderá ter de esperar o thread proprietário liberar o recurso-alvo. O thread em espera tem uma dependência do thread proprietário para aquele recurso em particular. Em uma instância do Mecanismo de Banco de Dados, as sessões podem entrar em impasse ao adquirir recursos não relacionados ao banco de dados, como memória ou threads.
Na ilustração, a transação T1 depende da transação T2 para o recurso de bloqueio da tabela Part. Da mesma forma, a transação T2 depende da transação T1 para o recurso de bloqueio da tabela Supplier. Devido a essas dependências formarem um ciclo, há um deadlock entre as transações T1 e T2.
Aqui está uma ilustração mais geral de um deadlock:
A tarefa T1 tem um bloqueio no recurso R1 (indicado pela seta de R1 para T1), e solicitou um bloqueio no recurso R2 (indicado pela seta de T1 para R2).
A tarefa T2 tem um bloqueio no recurso R2 (indicado pela seta de R2 a T2), e solicitou um bloqueio no recurso R1 (indicado pela seta de T2 a R1).
Como nenhuma tarefa pode continuar até que um recurso esteja disponível e nenhum recurso pode ser liberado até que uma tarefa continue, ocorre um estado de deadlock.
Note
O Mecanismo de Banco de Dados detecta automaticamente ciclos de deadlock. Ele escolhe uma das transações como vítima de deadlock e termina a transação com um erro para quebrar o deadlock.
Recursos que podem causar deadlock
Cada sessão de usuário pode ter uma ou mais tarefas sendo executadas em seu nome, sendo que cada tarefa pode adquirir ou aguardar para adquirir recursos. Os tipos de recursos a seguir podem causar bloqueio que pode resultar em um deadlock.
Locks. A espera para adquirir bloqueios em recursos, como objetos, páginas, linhas, metadados e aplicativos, pode causar um deadlock. Por exemplo, a transação T1 tem um bloqueio compartilhado (
S) na linha r1 e está aguardando para obter um bloqueio exclusivo (X) no r2. A transação T2 tem um bloqueio compartilhado (S) no r2 e está aguardando para obter um bloqueio exclusivo (X) na linha r1. Isso resulta em um ciclo de bloqueio no qual T1 e T2 esperam que uma libere os recursos bloqueados da outra.Threads de execução. Uma tarefa enfileirada à espera de um thread de trabalho disponível pode causar um deadlock. Se a tarefa em fila possuir recursos que estão bloqueando todos os threads de trabalhado, haverá um deadlock. Por exemplo, a sessão S1 inicia uma transação e adquire um bloqueio compartilhado (
S) na linha r1 e, em seguida, entra em suspensão. As sessões ativas em execução em todos os threads de trabalho disponíveis estão tentando adquirir bloqueios exclusivos (X) para a linha r1. Como a sessão S1 não pode adquirir um thread de trabalho, ela não pode confirmar a transação e liberar o bloqueio na linha r1. Isso resulta em um deadlock.Memory. Quando solicitações simultâneas estão esperando por concessões de memória que não podem ser satisfeitas com a memória disponível, pode ocorrer um deadlock. Por exemplo, duas consultas simultâneas, Q1 e Q2, são executadas como funções definidas pelo usuário que adquirem 10MB e 20MB de memória, respectivamente. Se cada consulta precisar de 30 MB e a memória disponível total for de 20 MB, Q1 e Q2 deverão esperar uma pela outra para liberar memória, resultando em um deadlock.
Recursos relacionados à execução de consultas paralelas. Threads de coordenador, produtor ou consumidor associados a uma porta de troca podem bloquear uns aos outros, provocando um deadlock, normalmente ao incluir pelo menos um outro processo que não faz parte da consulta paralela. Além disso, quando uma consulta paralela inicia a execução, o Mecanismo de Banco de Dados determina o grau de paralelismo e o número de threads de trabalho necessários, com base na carga de trabalho atual. Se a carga de trabalho do sistema for alterada inesperadamente, por exemplo, quando novas consultas forem executadas no servidor ou o sistema ficar sem threads de trabalho, poderá ocorrer um deadlock.
Recursos MARS (conjunto de resultados ativos múltiplos). Esses recursos são usados para controlar a intercalação de várias solicitações ativas em MARS. Para obter mais informações, consulte Usando MARS (conjuntos de resultados ativos múltiplos) no SQL Server Native Client.
Recurso do usuário. Quando um thread está esperando por um recurso que é potencialmente controlado por um aplicativo de usuário, o recurso é considerado como externo ou recurso de usuário e é tratado como um bloqueio.
Mutex de sessão. As tarefas que estão sendo executadas em uma sessão são intercaladas, ou seja, apenas uma tarefa pode ser executada na sessão em um determinado momento. Antes de a tarefa ser executada, deve ter acesso exclusivo ao mutex de sessão.
Mutex de transação. Todas as tarefas que estão sendo executadas em uma transação são intercaladas, ou seja, somente uma tarefa pode ser executada na transação em um determinado momento. Antes da tarefa ser executada, deve ter acesso exclusivo ao mutex de transação.
Para que uma tarefa seja executada em MARS, ela deve adquirir o mutex da sessão. Se a tarefa estiver sendo executada em uma transação, deverá adquirir o mutex de transação. Isso garante que apenas uma tarefa esteja ativa em um determinado momento, sessão e transação. Quando os mutexes solicitados forem adquiridos, a tarefa poderá ser executada. Quando a tarefa termina, ou está no meio da solicitação, primeiro ela libera o mutex de transação, depois o mutex de sessão, em ordem reversa de aquisição. Porém, podem ocorrer deadlocks com esses recursos. No pseudocódigo a seguir, duas tarefas, a solicitação do usuário U1 e a solicitação do usuário U2, estão sendo executadas na mesma sessão.
U1: Rs1=Command1.Execute("insert sometable EXEC usp_someproc"); U2: Rs2=Command2.Execute("select colA from sometable");O procedimento armazenado que está sendo executado na solicitação U1 adquiriu o mutex de sessão. Se o procedimento armazenado levar muito tempo para ser executado, é assumido pelo Mecanismo de Banco de Dados que o procedimento armazenado está aguardando a entrada do usuário. A solicitação de usuário U2 está esperando pelo mutex de sessão, enquanto o usuário está esperando pelo conjunto de resultados de U2, e U1 está esperando por um recurso de usuário. Esse estado de deadlock é logicamente ilustrado como:
Os deadlocks também podem ocorrer quando uma tabela é particionada e a configuração LOCK_ESCALATION de ALTER TABLE é definida como AUTO. Quando LOCK_ESCALATION é definido como AUTO, a simultaneidade aumenta permitindo que o Mecanismo de Banco de Dados bloqueie partições de tabela no nível HoBT em vez de no nível da tabela. Entretanto, quando transações separadas mantêm bloqueios de partição em uma tabela e querem um bloqueio em algum lugar de outra partição de transações, isso causa um deadlock. Esse tipo de deadlock pode ser evitado configurando LOCK_ESCALATION como TABLE. Porém, essa configuração reduz a simultaneidade forçando importantes atualizações em uma partição a aguardar um bloqueio de tabela.
Detecção de deadlock
Todos os recursos listados na seção Recursos que podem causar deadlock participam do esquema de detecção de deadlock do Mecanismo de Banco de Dados. A detecção de deadlock é realizada por um thread de monitoração de bloqueio que periodicamente inicia uma pesquisa em todas as tarefas em uma instância do Mecanismo de Banco de Dados. Os seguintes pontos descrevem o processo de pesquisa:
O intervalo padrão é de 5 segundos.
Se o thread de monitor de bloqueio localiza deadlocks, o intervalo de detecção de deadlock diminui de 5 segundos para até 100 milissegundos, dependendo da frequência de deadlocks.
Se o thread do monitor de bloqueio parar de localizar deadlocks, o Mecanismo de Banco de Dados aumentará os intervalos entre pesquisas para 5 segundos.
Se um deadlock for detectado, supõe-se que os novos threads que devem aguardar um bloqueio estejam entrando no ciclo de deadlock. As primeiras esperas de bloqueio após a detecção de um deadlock disparam imediatamente uma pesquisa de deadlock em vez de aguardar pelo próximo intervalo de detecção de deadlock. Por exemplo, se o intervalo atual for de 5 segundos, e um deadlock tiver sido detectado há pouco tempo, a próxima espera de bloqueio dispara o detector de deadlock imediatamente. Se essa espera de bloqueio fizer parte de um deadlock, ela será detectada imediatamente, em vez de durante a próxima pesquisa de deadlock.
Normalmente, o Mecanismo de Banco de Dados executa apenas a detecção de deadlock periódico. Como o número de deadlocks encontrados no sistema geralmente é pequeno, a detecção periódica de deadlocks contribui para reduzir a sobrecarga da detecção dos deadlocks no sistema.
Quando o monitor de bloqueio inicia a pesquisa de deadlock para um determinado thread, ele identifica o recurso em que o thread está esperando. O monitor de bloqueio localiza os proprietários desse recurso em particular e, recursivamente, continua a pesquisa de deadlock para esses threads até encontrar um ciclo. Um ciclo identificado dessa maneira forma um deadlock.
Depois que um deadlock é detectado, o Mecanismo de Banco de Dados encerra um deadlock escolhendo um dos tópicos como vítima de deadlock. O Mecanismo de Banco de Dados encerra o lote atual que está sendo executado para o thread, reverte a transação da vítima de deadlock e retorna o erro 1205 para o aplicativo. A reversão da transação da vítima de deadlock libera todos os bloqueios mantidos pela transação. Isso permite que as transações dos outros threads sejam desbloqueadas e prossigam. O erro 1205 (vítima de deadlock) registra informações sobre o tipo de recursos envolvidos em um deadlock.
Por padrão, o Mecanismo de Banco de Dados escolhe a transação que executa a transação que é a menos cara para reverter como vítima de deadlock. Como alternativa, um usuário pode especificar a prioridade de sessões em uma situação de deadlock usando a instrução SET DEADLOCK_PRIORITY.
DEADLOCK_PRIORITY pode ser definido como LOW, NORMALou HIGHou, como alternativa, pode ser definido como qualquer valor inteiro no intervalo de -10 a 10. Em determinados casos, o Mecanismo de Banco de Dados pode optar por alterar, temporariamente, a prioridade de deadlock para obter melhores resultados de concorrência.
A prioridade de impasse usa NORMAL como padrão, ou 0. Se duas sessões tiverem prioridades de deadlock diferentes, a transação na sessão com a prioridade mais baixa será escolhida como vítima de deadlock. Se ambas as sessões tiverem a mesma prioridade de deadlock, a transação menos cara para reverter será escolhida. Se as sessões envolvidas no ciclo de deadlock tiverem a mesma prioridade de deadlock e o mesmo custo, a vítima será escolhida aleatoriamente. Uma tarefa que está sendo revertida não pode ser escolhida como vítima de deadlock.
Ao trabalhar com o Common Language Runtime (CLR), o monitor de deadlock detecta automaticamente deadlocks em recursos de sincronização (monitores, bloqueio de leitura/escrita e junção de thread) acessados dentro de procedimentos gerenciados. Entretanto, o deadlock é resolvido ao se lançar uma exceção no procedimento selecionado como a vítima de deadlock. É importante entender que a exceção não libera automaticamente os recursos pertencentes à vítima; os recursos devem ser liberados explicitamente. Em consonância com o comportamento de exceção, a exceção usada para identificar uma vítima de deadlock pode ser capturada e ignorada.
Ferramentas de informações de deadlocks
Para exibir informações de deadlock, o Mecanismo de Banco de Dados fornece ferramentas de monitoramento na forma do xml_deadlock_report evento estendido, dois sinalizadores de rastreamento e o evento de grafo deadlock no SQL Profiler.
O xml_deadlock_report evento estendido é o método recomendado para capturar informações de deadlock.
Evento Estendido de Deadlock
No SQL Server 2012 (11.x) e versões posteriores, o evento estendido xml_deadlock_report deve ser usado em vez da classe de evento "deadlock graph" no SQL Trace ou SQL Profiler.
A sessão de eventos system_health captura xml_deadlock_report eventos por padrão. Esses eventos contêm o grafo de deadlock. Como a system_health sessão está habilitada por padrão, você não precisa configurar uma sessão de evento separada para capturar informações de deadlock.
O grafo de deadlock capturado geralmente tem três nós distintos:
-
victim-list. O identificador de processo da vítima do deadlock. -
process-list. Informações sobre todos os processos envolvidos no deadlock. -
resource-list. Informações sobre os recursos envolvidos no deadlock.
Você pode exibir os event_file dados de destino da system_health sessão no Management Studio. Se algum xml_deadlock_report evento tiver ocorrido, o Management Studio apresentará uma representação gráfica das tarefas e recursos envolvidos em um deadlock, como visto no exemplo a seguir:
A consulta a seguir pode exibir todos os eventos de deadlock capturados pelo ring_buffer destino da sessão system_health:
SELECT xdr.value('@timestamp', 'datetime') AS deadlock_time,
xdr.query('.') AS event_data
FROM (SELECT CAST ([target_data] AS XML) AS target_data
FROM sys.dm_xe_session_targets AS xt
INNER JOIN sys.dm_xe_sessions AS xs
ON xs.address = xt.event_session_address
WHERE xs.name = N'system_health'
AND xt.target_name = N'ring_buffer') AS XML_Data
CROSS APPLY Target_Data.nodes('RingBufferTarget/event[@name="xml_deadlock_report"]') AS XEventData(xdr)
ORDER BY deadlock_time DESC;
Aqui está o conjunto de resultados.
O exemplo a seguir mostra um exemplo da saída da event_data coluna:
<event name="xml_deadlock_report" package="sqlserver" timestamp="2022-02-18T08:26:24.698Z">
<data name="xml_report">
<type name="xml" package="package0" />
<value>
<deadlock>
<victim-list>
<victimProcess id="process27b9b0b9848" />
</victim-list>
<process-list>
<process id="process27b9b0b9848" taskpriority="0" logused="0" waitresource="KEY: 5:72057594214350848 (1a39e6095155)" waittime="1631" ownerId="11088595" transactionname="SELECT" lasttranstarted="2022-02-18T00:26:23.073" XDES="0x27b9f79fac0" lockMode="S" schedulerid="9" kpid="15336" status="suspended" spid="62" sbid="0" ecid="0" priority="0" trancount="0" lastbatchstarted="2022-02-18T00:26:22.893" lastbatchcompleted="2022-02-18T00:26:22.890" lastattention="1900-01-01T00:00:00.890" clientapp="SQLCMD" hostname="ContosoServer" hostpid="7908" loginname="CONTOSO\user" isolationlevel="read committed (2)" xactid="11088595" currentdb="5" lockTimeout="4294967295" clientoption1="538968096" clientoption2="128056">
<executionStack>
<frame procname="AdventureWorks2022.dbo.p1" line="3" stmtstart="78" stmtend="180" sqlhandle="0x0300050020766505ca3e07008ba8000001000000000000000000000000000000000000000000000000000000">
SELECT c2, c3 FROM t1 WHERE c2 BETWEEN @p1 AND @p1+ </frame>
<frame procname="adhoc" line="4" stmtstart="82" stmtend="98" sqlhandle="0x020000006263ec01ebb919c335024a072a2699958d3fcce60000000000000000000000000000000000000000">
unknown </frame>
</executionStack>
<inputbuf>
SET NOCOUNT ON
WHILE (1=1)
BEGIN
EXEC p1 4
END
</inputbuf>
</process>
<process id="process27b9ee33c28" taskpriority="0" logused="252" waitresource="KEY: 5:72057594214416384 (e5b3d7e750dd)" waittime="1631" ownerId="11088593" transactionname="UPDATE" lasttranstarted="2022-02-18T00:26:23.073" XDES="0x27ba15a4490" lockMode="X" schedulerid="6" kpid="5584" status="suspended" spid="58" sbid="0" ecid="0" priority="0" trancount="2" lastbatchstarted="2022-02-18T00:26:22.890" lastbatchcompleted="2022-02-18T00:26:22.890" lastattention="1900-01-01T00:00:00.890" clientapp="SQLCMD" hostname="ContosoServer" hostpid="15316" loginname="CONTOSO\user" isolationlevel="read committed (2)" xactid="11088593" currentdb="5" lockTimeout="4294967295" clientoption1="538968096" clientoption2="128056">
<executionStack>
<frame procname="AdventureWorks2022.dbo.p2" line="3" stmtstart="76" stmtend="150" sqlhandle="0x03000500599a5906ce3e07008ba8000001000000000000000000000000000000000000000000000000000000">
UPDATE t1 SET c2 = c2+1 WHERE c1 = @p </frame>
<frame procname="adhoc" line="4" stmtstart="82" stmtend="98" sqlhandle="0x02000000008fe521e5fb1099410048c5743ff7da04b2047b0000000000000000000000000000000000000000">
unknown </frame>
</executionStack>
<inputbuf>
SET NOCOUNT ON
WHILE (1=1)
BEGIN
EXEC p2 4
END
</inputbuf>
</process>
</process-list>
<resource-list>
<keylock hobtid="72057594214350848" dbid="5" objectname="AdventureWorks2022.dbo.t1" indexname="cidx" id="lock27b9dd26a00" mode="X" associatedObjectId="72057594214350848">
<owner-list>
<owner id="process27b9ee33c28" mode="X" />
</owner-list>
<waiter-list>
<waiter id="process27b9b0b9848" mode="S" requestType="wait" />
</waiter-list>
</keylock>
<keylock hobtid="72057594214416384" dbid="5" objectname="AdventureWorks2022.dbo.t1" indexname="idx1" id="lock27afa392600" mode="S" associatedObjectId="72057594214416384">
<owner-list>
<owner id="process27b9b0b9848" mode="S" />
</owner-list>
<waiter-list>
<waiter id="process27b9ee33c28" mode="X" requestType="wait" />
</waiter-list>
</keylock>
</resource-list>
</deadlock>
</value>
</data>
</event>
Bandeira de rastreamento 1204 e 1222
Quando ocorrem deadlocks e o sinalizador de rastreamento 1204 ou sinalizador de rastreamento 1222 está habilitado, os detalhes do deadlock são relatados no log de erros do SQL Server. O flag de rastreamento 1204 relata informações de deadlock formatadas por cada nó que participa do deadlock. O sinalizador de rastreamento 1222 formata informações de deadlock, primeiro por processos e depois por recursos. É possível permitir que ambos os sinalizadores de rastreamento obtenham duas representações do mesmo evento de deadlock.
Important
Evite usar sinalizadores de rastreamento 1204 e 1222 em sistemas com uso intensivo de carga de trabalho que estão enfrentando deadlocks. O uso desses sinalizadores de rastreamento pode introduzir problemas de desempenho. Em vez disso, use o evento estendido Deadlock para capturar as informações necessárias.
Além de definir as propriedades dos sinalizadores de rastreamento 1204 e 1222, a tabela a seguir também mostra as semelhanças e as diferenças.
| Property | Bandeira de rastreamento 1204 e 1222 | Sinalizador de rastreamento 1204 somente | Sinalizador de rastreamento 1222 somente |
|---|---|---|---|
| Formato da saída | A saída é capturada no log de erros do SQL Server. | Focado nos nós envolvidos no deadlock. Cada nó tem uma seção dedicada e a seção final descreve a vítima de deadlock. | Retorna informações em um formato parecido com XML que não está em conformidade com uma definição de esquema XML (XSD). O formato tem três seções principais. A primeira seção declara a vítima de deadlock. A segunda seção descreve cada processo envolvido no deadlock. A terceira seção descreve os recursos que são sinônimos de nós no sinalizador de rastreamento 1204. |
| Identificando atributos |
SPID:<x> ECID:<x>. Identifica o thread de ID da sessão em casos de processos paralelos. A entrada SPID:<x> ECID:0, em que <x> é substituído pelo valor do SPID, representa o thread principal. A entrada SPID:<x> ECID:<y>, em que <x> é substituída pelo valor SPID e <y> é maior que 0, representa o contexto de execução para o mesmo SPID.BatchID (sbid para o sinalizador de rastreamento 1222). Identifica o lote do qual a execução de código está solicitando ou mantendo um bloqueio. Quando vários conjuntos de resultados ativos (MARS) estão desabilitados, o valor BatchID é 0. Quando MARS está habilitado, o valor para lotes ativos é 1 para n. Se não houver lotes ativos na sessão, BatchID será 0.Mode Especifica o tipo de bloqueio de um determinado recurso que é solicitado, concedido ou aguardado por um thread. O modo pode ser Intent Shared (IS), Compartilhado (S), Atualizar (U), Intent Exclusive (IX), Compartilhado com Intent Exclusive (SIX) e Exclusivo (X).Line # (line para o sinalizador de rastreamento 1222). Lista o número de linha no lote atual de instruções que estava sendo executado quando o deadlock aconteceu.Input Buf (inputbuf para o sinalizador de rastreamento 1222). Lista todas as instruções no lote atual. |
Node Representa o número de entrada na cadeia de deadlock.Lists O proprietário do bloqueio pode fazer parte destas listas:Grant List Enumera os proprietários atuais do recurso.Convert List Enumera os proprietários atuais que estão tentando converter seus bloqueios em um nível mais alto.Wait List Enumera as novas solicitações de bloqueio do recurso.Statement Type Descreve o tipo de instrução (SELECT, INSERT, UPDATEou DELETE) na qual os threads têm permissões.Victim Resource Owner Especifica o thread participante que o Mecanismo de Banco de Dados escolhe como vítima para interromper o ciclo de deadlock. O thread escolhido e todos os contextos de execução são encerrados.Next Branch Representa os dois ou mais contextos de execução do mesmo SPID envolvidos no ciclo de deadlock. |
deadlock victim Representa o endereço de memória física da tarefa (consulte sys.dm_os_tasks) que foi selecionada como vítima de deadlock. O valor pode ser zero no caso de um deadlock não resolvido.executionstack Representa a pilha de chamadas do Transact-SQL que está sendo executada no momento em que ocorre o deadlock.priority Representa a prioridade do deadlock.logused Espaço de log usado pela tarefa.owner id A ID da transação que tem controle da solicitação.status O estado da tarefa. Para obter mais informações, consulte sys.dm_os_tasks.waitresource O recurso exigido pela tarefa.waittime O tempo em milissegundos de espera pelo recurso.schedulerid O agendador associado a essa tarefa. Veja sys.dm_os_schedulers.hostname O nome da estação de trabalho.isolationlevel O nível de isolamento da transação atual.Xactid A ID da transação que tem controle da solicitação.currentdb A ID do banco de dados.lastbatchstarted A última vez em que um processo cliente iniciou uma execução em lote.lastbatchcompleted A última vez em que um processo cliente concluiu uma execução em lote.clientoption1 e clientoption2 as opções definidas nesta sessão. Esses valores são máscaras de bits que representam as opções geralmente controladas por SET declarações como SET NOCOUNT e SET XACTABORT. Para obter mais informações, consulte @@OPTIONS.associatedObjectId Representa a ID de HoBT (heap ou árvore B). |
| Atributos do recurso |
RID identifica a única linha dentro de uma tabela na qual um bloqueio é mantido ou solicitado. O RID é representado como RID: db_id:file_id:page_no:row_no. Por exemplo, RID: 6:1:20789:0.OBJECT identifica a tabela na qual um bloqueio é mantido ou solicitado. O OBJECT é representado como OBJECT: db_id:object_id. Por exemplo, TAB: 6:2009058193.KEY Identifica o intervalo de chave dentro de um índice em que um bloqueio é mantido ou solicitado. KEY é representado como KEY: db_id:hobt_id (valor de hash da chave de índice). Por exemplo, KEY: 6:72057594057457664 (350007a4d329).PAG Identifica o recurso de página no qual um bloqueio é mantido ou solicitado. O PAG é representado como PAG: db_id:file_id:page_no. Por exemplo, PAG: 6:1:20789.EXT Identifica a estrutura de extensão. O EXT é representado como EXT: db_id:file_id:extent_no. Por exemplo, EXT: 6:1:9.DB Identifica o bloqueio de banco de dados.
DB é representado de um dos seguintes modos:DB: db_idDB: db_id[BULK-OP-DB], que identifica o bloqueio de banco de dados feito pelo backup.DB: db_id[BULK-OP-LOG], que identifica o bloqueio feito pelo backup de log.APP Identifica um bloqueio de aplicativo. O APP é representado como APP: lock_resource. Por exemplo, APP: Formf370f478.METADATA Representa os recursos de metadados envolvidos em um deadlock. Como METADATA tem muitos sub-recursos, o valor retornado depende do sub-recurso envolvido no deadlock. Por exemplo, METADATA.USER_TYPE retorna user_type_id = *integer_value*. Para obter mais informações sobre os recursos e sub-recursos METADATA, consulte sys.dm_tran_locks.HOBT Representa um heap ou árvore B envolvida em um deadlock. |
Nenhum exclusivo para esse sinalizador de rastreamento. | Nenhum exclusivo para esse sinalizador de rastreamento. |
Exemplo do sinalizador de rastreamento 1204
O exemplo a seguir mostra a saída quando o sinalizador de rastreamento 1204 está ativado. Neste caso, a tabela em Node 1 é um heap sem índices, e a tabela em Node 2 é um heap com índices não clusterizados. A chave de índice em Node 2 é atualizada quando o deadlock ocorre.
Deadlock encountered .... Printing deadlock information
Wait-for graph
Node:1
RID: 6:1:20789:0 CleanCnt:3 Mode:X Flags: 0x2
Grant List 0:
Owner:0x0315D6A0 Mode: X
Flg:0x0 Ref:0 Life:02000000 SPID:55 ECID:0 XactLockInfo: 0x04D9E27C
SPID: 55 ECID: 0 Statement Type: UPDATE Line #: 6
Input Buf: Language Event:
BEGIN TRANSACTION
EXEC usp_p2
Requested By:
ResType:LockOwner Stype:'OR'Xdes:0x03A3DAD0
Mode: U SPID:54 BatchID:0 ECID:0 TaskProxy:(0x04976374) Value:0x315d200 Cost:(0/868)
Node:2
KEY: 6:72057594057457664 (350007a4d329) CleanCnt:2 Mode:X Flags: 0x0
Grant List 0:
Owner:0x0315D140 Mode: X
Flg:0x0 Ref:0 Life:02000000 SPID:54 ECID:0 XactLockInfo: 0x03A3DAF4
SPID: 54 ECID: 0 Statement Type: UPDATE Line #: 6
Input Buf: Language Event:
BEGIN TRANSACTION
EXEC usp_p1
Requested By:
ResType:LockOwner Stype:'OR'Xdes:0x04D9E258
Mode: U SPID:55 BatchID:0 ECID:0 TaskProxy:(0x0475E374) Value:0x315d4a0 Cost:(0/380)
Victim Resource Owner:
ResType:LockOwner Stype:'OR'Xdes:0x04D9E258
Mode: U SPID:55 BatchID:0 ECID:0 TaskProxy:(0x0475E374) Value:0x315d4a0 Cost:(0/380)
Exemplo do sinalizador de rastreamento 1222
O exemplo a seguir mostra a saída quando o sinalizador de rastreamento 1222 está ativado. Neste caso, uma tabela é um heap sem índices, e a outra tabela é um heap com um índice não clusterizado. Na segunda tabela, a chave de índice é atualizada quando o deadlock ocorre.
deadlock-list
deadlock victim=process689978
process-list
process id=process6891f8 taskpriority=0 logused=868
waitresource=RID: 6:1:20789:0 waittime=1359 ownerId=310444
transactionname=user_transaction
lasttranstarted=2022-02-05T11:22:42.733 XDES=0x3a3dad0
lockMode=U schedulerid=1 kpid=1952 status=suspended spid=54
sbid=0 ecid=0 priority=0 transcount=2
lastbatchstarted=2022-02-05T11:22:42.733
lastbatchcompleted=2022-02-05T11:22:42.733
clientapp=Microsoft SQL Server Management Studio - Query
hostname=TEST_SERVER hostpid=2216 loginname=DOMAIN\user
isolationlevel=read committed (2) xactid=310444 currentdb=6
lockTimeout=4294967295 clientoption1=671090784 clientoption2=390200
executionStack
frame procname=AdventureWorks2022.dbo.usp_p1 line=6 stmtstart=202
sqlhandle=0x0300060013e6446b027cbb00c69600000100000000000000
UPDATE T2 SET COL1 = 3 WHERE COL1 = 1;
frame procname=adhoc line=3 stmtstart=44
sqlhandle=0x01000600856aa70f503b8104000000000000000000000000
EXEC usp_p1
inputbuf
BEGIN TRANSACTION
EXEC usp_p1
process id=process689978 taskpriority=0 logused=380
waitresource=KEY: 6:72057594057457664 (350007a4d329)
waittime=5015 ownerId=310462 transactionname=user_transaction
lasttranstarted=2022-02-05T11:22:44.077 XDES=0x4d9e258 lockMode=U
schedulerid=1 kpid=3024 status=suspended spid=55 sbid=0 ecid=0
priority=0 transcount=2 lastbatchstarted=2022-02-05T11:22:44.077
lastbatchcompleted=2022-02-05T11:22:44.077
clientapp=Microsoft SQL Server Management Studio - Query
hostname=TEST_SERVER hostpid=2216 loginname=DOMAIN\user
isolationlevel=read committed (2) xactid=310462 currentdb=6
lockTimeout=4294967295 clientoption1=671090784 clientoption2=390200
executionStack
frame procname=AdventureWorks2022.dbo.usp_p2 line=6 stmtstart=200
sqlhandle=0x030006004c0a396c027cbb00c69600000100000000000000
UPDATE T1 SET COL1 = 4 WHERE COL1 = 1;
frame procname=adhoc line=3 stmtstart=44
sqlhandle=0x01000600d688e709b85f8904000000000000000000000000
EXEC usp_p2
inputbuf
BEGIN TRANSACTION
EXEC usp_p2
resource-list
ridlock fileid=1 pageid=20789 dbid=6 objectname=AdventureWorks2022.dbo.T2
id=lock3136940 mode=X associatedObjectId=72057594057392128
owner-list
owner id=process689978 mode=X
waiter-list
waiter id=process6891f8 mode=U requestType=wait
keylock hobtid=72057594057457664 dbid=6 objectname=AdventureWorks2022.dbo.T1
indexname=nci_T1_COL1 id=lock3136fc0 mode=X
associatedObjectId=72057594057457664
owner-list
owner id=process6891f8 mode=X
waiter-list
waiter id=process689978 mode=U requestType=wait
Evento gráfico de deadlock do Profiler
O SQL Profiler tem um evento que apresenta uma representação gráfica das tarefas e recursos envolvidos em um deadlock. O exemplo a seguir mostra a saída do SQL Profiler quando o evento de grafo de deadlock é ativado.
Os recursos do SQL Profiler e do Rastreamento de SQL são preteridos e substituídos por Eventos Estendidos. Os Eventos Estendidos têm uma sobrecarga de desempenho menor e são mais configuráveis do que o Rastreamento de SQL. Considere usar o evento de deadlock de Eventos Estendidos em vez de rastrear deadlocks utilizando o SQL Profiler.
Para obter mais informações sobre o evento de deadlock, veja Classe de evento Lock:Deadlock. Para obter mais informações sobre grafos de deadlock do SQL Profiler, consulte Salvar grafos de deadlock (SQL Server Profiler).
Os Eventos Estendidos oferecem equivalentes às classes de eventos do SQL Trace. Para obter mais informações, consulte Exibir os equivalentes de eventos estendidos às classes de evento de rastreamento do SQL. Recomenda-se o uso de Eventos Estendidos em vez de SQL Trace.
Gerenciar deadlocks
Quando uma instância do Mecanismo de Banco de Dados escolhe uma transação como vítima de deadlock, ela encerra o lote atual, reverte a transação e retorna o erro 1205 para o aplicativo. A mensagem retornada é estruturada da seguinte maneira:
Your transaction (process ID #...) was deadlocked on {lock | communication buffer | thread} resources with another process and has been chosen as the deadlock victim. Rerun your transaction.
Como qualquer aplicativo que envia Transact-SQL consultas pode ser escolhido como vítima de deadlock, os aplicativos devem ter um manipulador de erros que possa lidar com o erro 1205. Se um aplicativo não lidar com o erro, o aplicativo poderá continuar sem saber que sua transação foi revertida.
Implementar um manipulador de erros que captura o erro 1205 permite que um aplicativo manipule deadlocks e execute uma ação corretiva (por exemplo, reenviar automaticamente a consulta envolvida no deadlock).
O aplicativo deveria pausar brevemente antes de enviar novamente a consulta. Isso dá à outra transação envolvida no deadlock a chance de concluir e liberar seus bloqueios. A randomização da duração da pausa minimiza a probabilidade de o deadlock ocorrer novamente quando a consulta reenviada solicita seus bloqueios. Por exemplo, o manipulador de erros pode ser codificado para pausar por uma duração aleatória entre um e três segundos.
Lidar com TRY...CATCH
Você pode usar TRY... CATCH para lidar com deadlocks. O erro 1205 pode ser capturado pelo bloco CATCH.
Para obter mais informações, consulte Como lidar com deadlocks.
Minimizar deadlocks (bloqueios)
Embora deadlocks não possam ser completamente evitados, seguir certas convenções de codificação pode minimizar a chance de gerar um deadlock. Minimizar deadlocks pode aumentar a taxa de transferência da transação e pode reduzir a sobrecarga do sistema pois poucas transações são:
- Revertidas, desfazendo todo o trabalho executado pela transação.
- Reenviadas por aplicativos pois elas foram revertidas quando bloqueadas.
Para ajudar a minimizar deadlocks:
- Acesse objetos na mesma ordem.
- Evite a interação de usuário durante as transações.
- Mantenha as transações curtas e em um lote.
- Evite níveis de isolamento mais altos, como
REPEATABLE READeSERIALIZABLEquando não necessário. - Use um nível de isolamento com base em controle de versão de linha
- Habilite a opção
READ_COMMITTED_SNAPSHOTde banco de dados para usar o controle de versão de linha para transações usando oREAD COMMITTEDnível de isolamento. - Use transações de isolamento de instantâneo.
- Habilite a opção
- Use conexões associadas.
Acesse objetos na mesma ordem
Se todas as transações simultâneas acessarem objetos na mesma ordem, haverá menos chance de ocorrerem deadlocks. Por exemplo, se duas transações simultâneas obtiverem um bloqueio na tabela Supplier e depois na tabela Part, uma transação será bloqueada na tabela Supplier até que a outra transação seja concluída. Após a primeira transação ser confirmada ou revertida, a segunda continua e um deadlock não acontece. Usar procedimentos armazenados para todas as modificações de dados pode padronizar a ordem de acesso dos objetos.
Evite a interação de usuário durante as transações
Evite transações que incluam interação do usuário, pois a velocidade dos lotes em execução sem intervenção do usuário é muito mais rápida do que a velocidade em que um usuário deve responder manualmente às consultas, como responder a um prompt de um parâmetro solicitado por um aplicativo. Isto degrada a taxa de transferência do sistema, pois quaisquer bloqueios mantidos pela transação somente são liberados quando a transação é confirmada ou revertida. Mesmo que um deadlock não ocorra, outras transações que acessam os mesmos recursos serão bloqueadas enquanto aguardam a conclusão da transação.
Mantenha as transações curtas e em um lote
Um deadlock ocorre tipicamente quando várias transações demoradas são executadas simultaneamente no mesmo banco de dados. Quanto mais longa a transação, por mais tempo as atualizações e bloqueios exclusivos são mantidos, bloqueando outras atividades, e levando à possíveis situações de deadlock.
Manter transações em um lote minimiza as viagens de ida e volta de rede durante uma transação, reduzindo possíveis atrasos na conclusão da transação devido ao processamento do cliente.
Evitar níveis de isolamento mais altos
Determine se uma transação pode ser executada em um nível inferior de isolamento. O uso READ COMMITTED permite que uma transação leia dados lidos anteriormente (mas não modificados) por outra transação sem aguardar a conclusão da transação.
READ COMMITTED mantém bloqueios compartilhados por uma duração mais curta do que um nível de isolamento mais alto, como SERIALIZABLE. Isso reduz a contenção de bloqueio.
Use um nível de isolamento com base em controle de versão de linha
Quando a opção de banco de dados READ_COMMITTED_SNAPSHOT é definida ON, uma transação em execução no nível de isolamento READ COMMITTED utiliza versão de linha em vez de bloqueios compartilhados durante operações de leitura.
Dica
A Microsoft recomenda o nível de isolamento baseado em READ COMMITTED controle de versão de linha para todos os aplicativos, exceto se um aplicativo dependa do comportamento de bloqueio do nível de isolamento baseado em READ COMMITTED bloqueio.
O isolamento de instantâneo também usa controle de versão de linha, o qual não usa bloqueios compartilhados durante operações de leitura. Para que uma transação possa ser executada sob isolamento de instantâneo, a opção de banco de dados ALLOW_SNAPSHOT_ISOLATION deve ser definida como ON.
Use níveis de isolamento baseados em controle de versão de linha para minimizar bloqueios que podem ocorrer entre operações de leitura e gravação.
Use conexões associadas
Usar associações de saída usando, faz com que duas ou mais conexões abertas pelo mesmo aplicativo possam cooperar entre si. Qualquer bloqueio adquirido pelas conexões secundárias é mantido como se tivessem sido adquiridos pela conexão primária, e vice-versa. Portanto, eles não bloqueiam um ao outro.
Causa um deadlock
Talvez seja necessário causar um deadlock para fins de aprendizado ou demonstração.
O exemplo a AdventureWorksLT2019 seguir funciona no banco de dados de exemplo com o esquema e os dados padrão quando READ_COMMITTED_SNAPSHOT foi habilitado. Para baixar essa amostra, acesse Bancos de dados de amostra AdventureWorks.
Para obter um exemplo que causa um deadlock quando o bloqueio otimizado está habilitado, consulte Bloqueio otimizado e deadlocks.
Para provocar um deadlock, você precisará conectar duas sessões ao banco de dados AdventureWorksLT2019. Nos referimos a essas sessões como Sessão A e Sessão B. Você pode criar essas duas sessões criando duas janelas de consulta no SSMS (SQL Server Management Studio).
Na Sessão A, execute o lote a seguir. Esse código inicia uma transação explícita e executa uma instrução que atualiza a SalesLT.Product tabela. Para fazer isso, a transação adquire um bloqueio de atualização (U) nas linhas elegíveis na tabela SalesLT.Product, que são então convertidas em bloqueios exclusivos (X). Deixamos a transação aberta.
BEGIN TRANSACTION;
UPDATE SalesLT.Product
SET SellEndDate = SellEndDate + 1
WHERE Color = 'Red';
Agora, na Sessão B, execute o lote a seguir. Esse código não inicia uma transação explicitamente. Ele opera no modo de transação de confirmação automática. Essa instrução atualiza a tabela SalesLT.ProductDescription. A atualização utiliza um bloqueio de atualização (U) nas linhas qualificadas da tabela SalesLT.ProductDescription. A consulta se une a outras tabelas, incluindo a tabela SalesLT.Product.
UPDATE SalesLT.ProductDescription
SET Description = Description
FROM SalesLT.ProductDescription AS pd
INNER JOIN SalesLT.ProductModelProductDescription AS pmpd
ON pd.ProductDescriptionID = pmpd.ProductDescriptionID
INNER JOIN SalesLT.ProductModel AS pm
ON pmpd.ProductModelID = pm.ProductModelID
INNER JOIN SalesLT.Product AS p
ON pm.ProductModelID = p.ProductModelID
WHERE p.Color = 'Silver';
Para concluir essa atualização, a Sessão B precisa de bloqueios compartilhados (S) em linhas na tabelaSalesLT.Product, incluindo as linhas bloqueadas pela Sessão A. A sessão B está bloqueada.SalesLT.Product
Retorne à Sessão A. Execute a instrução a seguir UPDATE . Essa instrução é executada como parte da transação aberta anteriormente.
UPDATE SalesLT.ProductDescription
SET Description = Description
FROM SalesLT.ProductDescription AS pd
INNER JOIN SalesLT.ProductModelProductDescription AS pmpd
ON pd.ProductDescriptionID = pmpd.ProductDescriptionID
INNER JOIN SalesLT.ProductModel AS pm
ON pmpd.ProductModelID = pm.ProductModelID
INNER JOIN SalesLT.Product AS p
ON pm.ProductModelID = p.ProductModelID
WHERE p.Color = 'Red';
A segunda instrução de atualização na Sessão A será bloqueada pela Sessão B no SalesLT.ProductDescription.
Agora, a Sessão A e a Sessão B estão se bloqueando mutuamente. Nenhuma transação pode prosseguir, pois cada uma delas precisa de um recurso bloqueado pela outra.
Após alguns segundos, o monitor de deadlock identifica que as transações na Sessão A e na Sessão B estão se bloqueando mutuamente e que nenhuma delas consegue progredir. Você vê um deadlock ocorrer, com a Sessão A escolhida como a vítima do deadlock. A Sessão B é concluída com êxito. Uma mensagem de erro aparece na janela de consulta da Sessão A com texto semelhante ao seguinte exemplo:
Msg 1205, Level 13, State 51, Line 7
Transaction (Process ID 51) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.
Se um deadlock não for gerado, verifique se READ_COMMITTED_SNAPSHOT está habilitado no banco de dados de amostra. Os deadlocks podem ocorrer em qualquer configuração de banco de dados, mas este exemplo exige que READ_COMMITTED_SNAPSHOT esteja habilitado.
Você pode exibir os detalhes do deadlock no ring_buffer alvo da sessão de evento system_health, que está habilitada e ativa por padrão no SQL Server e na Instância Gerenciada do Azure SQL. Considere a consulta a seguir:
WITH cteDeadLocks ([Deadlock_XML])
AS (SELECT CAST (target_data AS XML) AS [Deadlock_XML]
FROM sys.dm_xe_sessions AS xs
INNER JOIN sys.dm_xe_session_targets AS xst
ON xs.[address] = xst.event_session_address
WHERE xs.[name] = 'system_health'
AND xst.target_name = 'ring_buffer')
SELECT x.Graph.query('(event/data/value/deadlock)[1]') AS Deadlock_XML,
x.Graph.value('(event/data/value/deadlock/process-list/process/@lastbatchstarted)[1]', 'datetime2(3)') AS when_occurred,
DB_Name(x.Graph.value('(event/data/value/deadlock/process-list/process/@currentdb)[1]', 'int')) AS DB --Current database of the first listed process
FROM (SELECT Graph.query('.') AS Graph
FROM cteDeadLocks AS c
CROSS APPLY c.[Deadlock_XML].nodes('RingBufferTarget/event[@name="xml_deadlock_report"]') AS Deadlock_Report(Graph)) AS x
ORDER BY when_occurred DESC;
Você pode exibir o XML na coluna Deadlock_XML dentro do SSMS, selecionando a célula que aparece como um hiperlink. Salve essa saída como um arquivo .xdl, feche e reabra o arquivo .xdl no SSMS para obter um gráfico visual de deadlocks. O grafo de deadlock deve ser semelhante à imagem a seguir.
Bloqueios e deadlocks otimizados
Com o bloqueio otimizado, os bloqueios de página e linha não são mantidos até o final da transação. Eles são lançados assim que uma linha é atualizada. Além disso, se READ_COMMITTED_SNAPSHOT estiver habilitado, os bloqueios de atualização (U) não serão usados. Como resultado, a probabilidade de interbloqueios é reduzida.
O exemplo anterior não causa um deadlock quando o bloqueio otimizado está habilitado porque depende dos bloqueios de atualização (U).
O exemplo a seguir pode ser usado para causar um deadlock em um banco de dados que tenha o bloqueio otimizado habilitado.
Primeiro, crie uma tabela de exemplo e adicione dados.
CREATE TABLE t2
(
a INT PRIMARY KEY NOT NULL,
b INT NULL
);
INSERT INTO t2
VALUES (1, 10),
(2, 20),
(3, 30);
Os lotes T-SQL a seguir, executados em sequência em duas sessões separadas, criam um deadlock.
Na sessão 1:
BEGIN TRANSACTION xactA;
UPDATE t2
SET b = b + 10
WHERE a = 1;
Na sessão 2:
BEGIN TRANSACTION xactB;
UPDATE t2
SET b = b + 10
WHERE a = 2;
Na sessão 1:
UPDATE t2
SET b = b + 100
WHERE a = 2;
Na sessão 2:
UPDATE t2
SET b = b + 20
WHERE a = 1;
Nesse caso, cada sessão mantém um bloqueio exclusivo (X) em seu próprio recurso de ID de transação (TID) e está aguardando o bloqueio compartilhado (S) no outro TID, resultando em um deadlock.
O relatório de deadlock abreviado a seguir contém elementos e atributos específicos ao bloqueio otimizado. Em cada recurso no relatório <resource-list>deadlock, cada <xactlock> elemento relata os recursos subjacentes e as informações de bloqueio de TID de cada membro de um deadlock.
<deadlock>
<victim-list>
<victimProcess id="process12994344c58" />
</victim-list>
<process-list>
<process id="process12994344c58" taskpriority="0" logused="272" waitresource="XACT: 23:2476:0 KEY: 23:72057594049593344 (8194443284a0)" waittime="447" ownerId="3234906" transactionname="xactA" lasttranstarted="2025-10-08T21:36:34.063" XDES="0x12984ba0480" lockMode="S" schedulerid="2" kpid="204928" status="suspended" spid="95" sbid="0" ecid="0" priority="0" trancount="2" lastbatchstarted="2025-10-08T21:36:40.857" lastbatchcompleted="2025-10-08T21:36:34.063" lastattention="2025-10-08T21:36:11.340" clientapp="Microsoft SQL Server Management Studio - Query" hostname="WS1" hostpid="23380" loginname="user1" isolationlevel="read committed (2)" xactid="3234906" currentdb="23" currentdbname="AdventureWorksLT" lockTimeout="4294967295" clientoption1="671090784" clientoption2="390200">
<inputbuf>
UPDATE t2
SET b = b + 20
WHERE a = 1;
</inputbuf>
</process>
<process id="process1299c969828" taskpriority="0" logused="272" waitresource="XACT: 23:2477:0 KEY: 23:72057594049593344 (61a06abd401c)" waittime="3083" ownerId="3234886" transactionname="xactB" lasttranstarted="2025-10-08T21:36:30.303" XDES="0x12995c84480" lockMode="S" schedulerid="2" kpid="63348" status="suspended" spid="88" sbid="0" ecid="0" priority="0" trancount="2" lastbatchstarted="2025-10-08T21:36:38.223" lastbatchcompleted="2025-10-08T21:36:30.303" lastattention="1900-01-01T00:00:00.303" clientapp="Microsoft SQL Server Management Studio - Query" hostname="WS1" hostpid="23380" loginname="user1" isolationlevel="read committed (2)" xactid="3234886" currentdb="23" currentdbname="AdventureWorksLT" lockTimeout="4294967295" clientoption1="671090784" clientoption2="390200">
<inputbuf>
UPDATE t2
SET b = b + 100
WHERE a = 2;
</inputbuf>
</process>
</process-list>
<resource-list>
<xactlock xdesIdLow="2476" xdesIdHigh="0" dbid="23" id="lock1299fa06c00" mode="X">
<UnderlyingResource>
<keylock hobtid="72057594049593344" dbid="23" objectname="e6fc405e-1ee8-49df-a2b3-54ee0151d851.dbo.t2" indexname="PK__t2__3BD0198ED3CBA65E" />
</UnderlyingResource>
<owner-list>
<owner id="process1299c969828" mode="X" />
</owner-list>
<waiter-list>
<waiter id="process12994344c58" mode="S" requestType="wait" />
</waiter-list>
</xactlock>
<xactlock xdesIdLow="2477" xdesIdHigh="0" dbid="23" id="lock129940b2380" mode="X">
<UnderlyingResource>
<keylock hobtid="72057594049593344" dbid="23" objectname="e6fc405e-1ee8-49df-a2b3-54ee0151d851.dbo.t2" indexname="PK__t2__3BD0198ED3CBA65E" />
</UnderlyingResource>
<owner-list>
<owner id="process12994344c58" mode="X" />
</owner-list>
<waiter-list>
<waiter id="process1299c969828" mode="S" requestType="wait" />
</waiter-list>
</xactlock>
</resource-list>
</deadlock>
Conteúdo relacionado
- Visão geral de eventos estendidos
- sys.dm_tran_locks (Transact-SQL)
- Classe de evento Deadlock Graph
- Deadlocks com o nível de isolamento repetível de leitura
- Classe de evento Lock:Deadlock Chain
- Classe de evento Lock:Deadlock
- SET DEADLOCK_PRIORITY (Transact-SQL)
- Analisar e evitar deadlocks no Banco de Dados SQL do Azure e no Banco de Dados SQL no Fabric
- Abrir, exibir e imprimir um arquivo de deadlock no SQL Server Management Studio (SSMS)