Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Aplica-se a:Banco de Dados SQL do
Azure
Instância Gerenciada de SQL do Azure
Azure Synapse Analytics
Analytics Platform System (PDW)
Banco de Dados SQL no Microsoft Fabric
Este artigo discute os impasses no Mecanismo de Banco de Dados em profundidade. Os impasses 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.
Entenda os impasses
Um interbloqueio ocorre quando duas ou mais tarefas bloqueiam permanentemente umas às outras porque cada tarefa possui um bloqueio num recurso que as outras tarefas estão a tentar 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 que tem 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 que tem na linha 1.
A transação A não pode ser concluída até que a transação B seja concluída, mas a transação B é bloqueada pela transação A. Esta 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 por ter uma dependência da transação A.
Ambas as transações num deadlock aguardam indefinidamente, a menos que o deadlock seja quebrado por um processo externo. O monitor de deadlock do Mecanismo de Banco de Dados verifica periodicamente se há tarefas que estão em um deadlock. Se o monitor detetar uma dependência cíclica, ele escolhe uma das tarefas como vítima e encerra a sua transação com um erro. Isso permite que a outra tarefa conclua sua transação. O aplicativo com a transação que terminou com um erro pode repetir a transação, que geralmente é concluída depois que a outra transação bloqueada é concluída.
O deadlock é muitas vezes confundido com o bloqueio normal. Quando uma transação solicita um bloqueio em um recurso bloqueado por outra transação, a transação solicitante aguarda até que o bloqueio seja liberado. Por padrão, as transações no Mecanismo de Banco de Dados não expiram, a menos que LOCK_TIMEOUT esteja definido. A transação solicitante está bloqueada, mas não em impasse, porque a transação solicitante não fez nada para bloquear a transação que possui o bloqueio. Eventualmente, a transação proprietária conclui e libera o bloqueio e, em seguida, a transação solicitante recebe o bloqueio e prossegue. Os impasses são resolvidos quase imediatamente, enquanto o bloqueio pode, em teoria, persistir indefinidamente. Os impasses são por vezes chamados de "abraço fatal".
Um deadlock pode ocorrer em qualquer sistema com vários threads, não apenas em um sistema de gerenciamento de banco de dados relacional, e pode ocorrer para recursos diferentes de bloqueios em objetos de banco de dados. Por exemplo, um thread em um sistema operacional multithreaded pode adquirir um ou mais recursos, como blocos de memória. Se o recurso que está sendo adquirido for atualmente de propriedade de outro thread, o primeiro thread pode ter que aguardar até que o thread proprietário libere o recurso de destino. Diz-se que o thread de espera tem uma dependência do thread proprietário para esse recurso específico. Em uma instância do Mecanismo de Banco de Dados, as sessões podem entrar em interbloqueio ao adquirir recursos não relacionados a banco de dados, como memória ou threads.
Na ilustração, a transação T1 tem uma dependência da transação T2 para o recurso de bloqueio da tabela Part. Da mesma forma, a transação T2 tem uma dependência da transação T1 para o recurso de bloqueio da tabela Supplier. Como essas dependências formam um ciclo, há um impasse entre as transações T1 e T2.
Aqui está uma ilustração mais geral de um impasse:
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 para T2) e solicitou um bloqueio no recurso R1 (indicado pela seta de T2 para R1).
Como nenhuma das tarefas pode continuar até que um recurso esteja disponível e nenhum recurso possa ser liberado até que uma tarefa continue, existe um estado de bloqueio.
Note
O Mecanismo de Banco de Dados deteta automaticamente ciclos de deadlock. Ele escolhe uma das transações como uma vítima de deadlock e a encerra com um erro para quebrar o deadlock.
Recursos que podem entrar em interbloqueio
Cada sessão de usuário pode ter uma ou mais tarefas em execução em seu nome, onde cada tarefa pode adquirir ou esperar para adquirir recursos. Os seguintes tipos de recursos podem causar bloqueio que pode resultar em um impasse.
Locks. Esperar para adquirir bloqueios em recursos, como objetos, páginas, linhas, metadados e aplicativos pode causar um impasse. Por exemplo, a transação T1 tem um bloqueio partilhado (
S) na linha r1 e está à espera de obter um bloqueio exclusivo (X) na linha r2. A transação T2 tem um bloqueio compartilhado (S) no r2 e está esperando para obter um bloqueio exclusivo (X) na linha r1. Isso resulta em um ciclo de bloqueio no qual T1 e T2 esperam um pelo outro para liberar os recursos bloqueados.Threads de trabalho. Uma tarefa em fila aguardando um thread de trabalho disponível pode causar um deadlock. Se a tarefa enfileirada possuir recursos que estão a bloquear todos os threads de trabalho, ocorrerá um impasse. Por exemplo, a sessão S1 inicia uma transação, adquire um bloqueio partilhado (
S) na linha r1 e depois vai dormir. As sessões ativas em execução em todos os threads de trabalho disponíveis estão tentando adquirir bloqueios exclusivos (X) na 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. Isto resulta num impasse.Memory. Quando solicitações simultâneas estão aguardando concessões de memória que não podem ser satisfeitas com a memória disponível, um deadlock pode ocorrer. Por exemplo, duas consultas simultâneas, Q1 e Q2, são executadas como funções definidas pelo usuário que adquirem 10 MB e 20 MB de memória, respectivamente. Se cada consulta precisar de 30 MB e a memória total disponível for de 20 MB, então Q1 e Q2 devem esperar um pelo outro para liberar memória, o que resulta em um impasse.
Recursos relacionados à execução de consultas paralelas. As threads de coordenador, produtor ou consumidor associadas a uma porta de intercâmbio podem bloquear umas às outras, causando um impasse geralmente quando inclui pelo menos um processo adicional 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 mudar inesperadamente, por exemplo, quando novas consultas começarem a ser executadas no servidor ou o sistema ficar sem threads de trabalho, poderá ocorrer um impasse.
Recursos MARS (Conjuntos de Resultados Ativos Múltiplos). Esses recursos são usados para controlar a intercalação de várias solicitações ativas no MARS. Para obter mais informações, consulte Usando vários conjuntos de resultados ativos (MARS) no SQL Server Native Client.
Recurso do utilizador. Quando um thread está aguardando um recurso que é potencialmente controlado por um aplicativo de usuário, o recurso é considerado um recurso externo ou de usuário e é tratado como um bloqueio.
Sessão mutex. As tarefas executadas em uma sessão são intercaladas, o que significa que apenas uma tarefa pode ser executada sob a sessão em um determinado momento. Antes que a tarefa possa ser executada, ela deve ter acesso exclusivo ao mutex da sessão.
Transação mutex. Todas as tarefas executadas em uma transação são intercaladas, o que significa que apenas uma tarefa pode ser executada sob a transação em um determinado momento. Antes que a tarefa possa ser executada, ela deve ter acesso exclusivo ao mutex da transação.
Para que uma tarefa seja executada sob MARS, ela deve adquirir o mutex de sessão. Se a tarefa estiver a ser executada numa transação, deverá então adquirir o mutex da transação. Isso garante que apenas uma tarefa esteja ativa ao mesmo tempo em uma determinada sessão e uma determinada transação. Uma vez que os mutexes necessários tenham sido adquiridos, a tarefa pode ser executada. Quando a tarefa termina ou cede no meio da solicitação, ela primeiro libera o mutex da transação, seguido pelo mutex da sessão, na ordem inversa da aquisição. No entanto, podem ocorrer impasses com esses recursos. No pseudocódigo a seguir, duas tarefas, solicitação de usuário U1 e solicitação de 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 executado a partir da solicitação do usuário U1 adquiriu o mutex de sessão. Se o procedimento armazenado demorar muito tempo para ser executado, o Mecanismo de Banco de Dados presumirá que o procedimento armazenado está aguardando a entrada do usuário. A solicitação do usuário U2 está aguardando o mutex da sessão enquanto o usuário está aguardando o conjunto de resultados do U2 e o U1 está aguardando um recurso do usuário. Este é um estado de impasse logicamente ilustrado como:
Os deadlocks também podem ocorrer quando uma tabela é particionada e a LOCK_ESCALATION configuração 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. No entanto, quando transações separadas mantêm bloqueios de partição em uma tabela e querem um bloqueio em algum lugar na outra partição de transações, isso causa um impasse. Este tipo de impasse pode ser evitado definindo LOCK_ESCALATION como TABLE. No entanto, essa configuração reduz a simultaneidade ao forçar que grandes atualizações em uma partição aguardem por um bloqueio de tabela.
Deteção de deadlock
Todos os recursos listados na seção Recursos que podem causar um impasse participam do esquema de deteção de impasse do Mecanismo de Banco de Dados. A deteção de deadlock é executada por um thread de monitoramento de bloqueio que inicia periodicamente uma pesquisa em todas as tarefas numa instância do motor de base de dados. Os seguintes pontos descrevem o processo de pesquisa:
O intervalo padrão é de 5 segundos.
Se o thread do monitor de bloqueio encontrar deadlocks, o intervalo de deteção de deadlock cai de 5 segundos para até 100 milissegundos, dependendo da frequência dos deadlocks.
Se o thread de monitorização de bloqueios parar de encontrar interbloqueios, o Mecanismo de Banco de Dados aumentará os intervalos entre as pesquisas para 5 segundos.
Se um impasse for detetado, presume-se que os novos threads que devem esperar por um bloqueio estão a entrar no ciclo de impasse. Os primeiros períodos de espera após a deteção de um deadlock acionam imediatamente uma pesquisa de deadlock, em vez de aguardar pelo próximo intervalo específico de deteção de deadlock. Por exemplo, se o intervalo atual for de 5 segundos e um deadlock tiver sido detetado, a próxima espera de bloqueio iniciará o detetor de deadlock imediatamente. Se essa espera de bloqueio fizer parte de um deadlock, ela será detetada imediatamente, em vez de durante a próxima pesquisa de deadlock.
O Mecanismo de Banco de Dados normalmente executa apenas a deteção periódica de deadlock. Como o número de deadlocks encontrados no sistema é geralmente pequeno, a deteção periódica de deadlocks ajuda a reduzir a sobrecarga de deteção de deadlocks no sistema.
Quando o monitor de bloqueio inicia a detecção de deadlock para um thread específico, ele identifica o recurso no qual o thread está esperando. Em seguida, o monitor de bloqueio encontra os proprietários desse recurso específico e, recursivamente, continua a pesquisa de bloqueio para esses threads até encontrar um ciclo. Um ciclo identificado desta forma forma forma um impasse.
Depois que um deadlock é detetado, o Mecanismo de Banco de Dados termina um deadlock escolhendo um dos processos como vítima do 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. Reverter a transação para a vítima de deadlock libera todos os bloqueios mantidos pela transação. Isso permite que as transações dos outros threads sejam desbloqueadas e continuem. O erro 1205 (vítima de deadlock) regista informações sobre os tipos de recursos envolvidos num deadlock.
Por padrão, o Mecanismo de Banco de Dados escolhe, como vítima de deadlock, a transação em execução que é a menos dispendiosa para reverter. Como alternativa, um usuário pode especificar a prioridade das sessões em uma situação de bloqueio usando a SET DEADLOCK_PRIORITY instrução.
DEADLOCK_PRIORITY pode ser definido como LOW, NORMALou , ou HIGH, alternativamente, pode ser definido como qualquer valor inteiro no intervalo de -10 a 10. Em certos casos, o Mecanismo de Banco de Dados pode optar por alterar a prioridade de bloqueio por um curto período para obter uma melhor simultaneidade.
A prioridade de impasse padrão é NORMAL, ou 0. Se duas sessões tiverem prioridades de bloqueio diferentes, a transação na sessão com a prioridade mais baixa será escolhida como a vítima do impasse. Se ambas as sessões tiverem a mesma prioridade de bloqueio, a transação que for menos dispendiosa para reverter será escolhida. Se as sessões envolvidas no ciclo de impasse tiverem a mesma prioridade de bloqueio e o mesmo custo, uma vítima é escolhida aleatoriamente. Uma tarefa que está revertendo não pode ser escolhida como uma vítima de impasse.
Ao trabalhar com CLR (Common Language Runtime), o monitor de deadlock deteta automaticamente deadlocks para recursos de sincronização (monitores, bloqueio de leitor/gravador e associação de threads) acessados dentro de procedimentos gerenciados. No entanto, o impasse é resolvido lançando uma exceção no procedimento que foi selecionado como vítima do impasse. É importante entender que a exceção não libera automaticamente recursos atualmente pertencentes à vítima; os recursos devem ser explicitamente liberados. Consistente com o comportamento de exceção, a exceção usada para identificar uma vítima de interbloqueio pode ser capturada e descartada.
Ferramentas de informação sobre impasses
Para exibir informações de deadlock, o Mecanismo de Banco de Dados fornece ferramentas de monitoramento na forma do evento estendido xml_deadlock_report, dois sinalizadores de rastreio e o evento de deadlock gráfico no SQL Profiler.
O xml_deadlock_report evento estendido é o método recomendado para capturar informações de deadlock.
Evento estendido de bloqueio
No SQL Server 2012 (11.x) e em versões posteriores, o evento estendido xml_deadlock_report deve ser usado em vez da classe de evento gráfico de deadlock no Rastreamento SQL ou no SQL Profiler.
A sessão de eventos system_health captura eventos por padrão. Esses eventos contêm o gráfico de deadlock. Como a sessão system_health está habilitada por padrão, não é necessário configurar uma sessão de evento separada para capturar informações de deadlock.
Normalmente, o gráfico do impasse capturado tem três nós diferentes:
-
victim-list. O identificador do processo da vítima de deadlock. -
process-list. Informações sobre todos os processos envolvidos no impasse. -
resource-list. Informações sobre os recursos envolvidos no impasse.
Você pode exibir os event_file dados de destino da system_health sessão no Management Studio. Se algum xml_deadlock_report evento ocorreu, 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 ring_buffer capturados pelo 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>
Sinalizador de rastreamento 1204 e sinalizador de rastreamento 1222
Quando ocorrem deadlocks e o sinalizador de rastreamento 1204 ou o sinalizador de rastreamento 1222 está habilitado, os detalhes do deadlock são relatados no log de erros do SQL Server. O sinalizador de rastreamento 1204 relata informações de bloqueio formatadas por cada nó envolvido no deadlock. O sinalizador de rastreamento 1222 formata informações de bloqueio, primeiro por processos e depois por recursos. É possível habilitar ambos os sinalizadores de rastreamento para obter duas representações do mesmo evento de deadlock.
Important
Evite usar sinalizadores de rastreamento 1204 e 1222 em sistemas com carga de trabalho intensiva que estão enfrentando bloqueios. O uso desses sinalizadores de rastreamento pode apresentar 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 diferenças.
| Property | Sinalizador de rastreamento 1204 e sinalizador de rastreamento 1222 | Apenas sinalizador de rastreamento 1204 | Apenas o sinalizador de rastreio 1222 |
|---|---|---|---|
| Formato de saída | A saída é capturada no log de erros do SQL Server. | Focado nos nós envolvidos no impasse. Cada nó tem uma seção dedicada, e a seção final descreve a vítima de deadlock. | Retorna informações em um formato semelhante a XML que não está em conformidade com um esquema XSD (XML Schema Definition). O formato tem três seções principais. A primeira seção declara a vítima do impasse. A segunda seção descreve cada processo envolvido no impasse. A terceira seção descreve os recursos que correspondem aos nós no sinalizador de rastreamento 1204. |
| Identificando atributos |
SPID:<x> ECID:<x>. Identifica o thread de ID de sessão em casos de processos paralelos. A entrada SPID:<x> ECID:0, onde <x> é substituído pelo valor SPID, representa o thread principal. A entrada SPID:<x> ECID:<y>, onde <x> é substituída pelo valor SPID e <y> é maior que 0, representa o contexto de execução para o mesmo SPID.BatchID (sbid para a bandeira de rastreio 1222). Identifica o lote do qual a execução de código está solicitando ou mantendo um bloqueio. Quando Multiple Ative Result Sets (MARS) está desativado, o valor BatchID é 0. Quando o MARS está habilitado, o valor para lotes ativos é de 1 a n. Se não houver lotes ativos na sessão, BatchID será 0.Mode Especifica o tipo de bloqueio para um recurso específico que é solicitado, concedido ou aguardado por um thread. O modo pode ser Intenção Compartilhada (IS), Compartilhada (S), Atualização (U), Intenção Exclusiva (IX), Compartilhada com Intenção Exclusiva (SIX) e Exclusiva (X).Line # (line para a bandeira de rastreio 1222). Lista o número da linha no lote atual de instruções que estava sendo executado quando o deadlock ocorreu.Input Buf (inputbuf para a bandeira de rastreio 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 cadeado 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 suas travas para um nível mais alto.Wait List Enumera as novas solicitações de bloqueio atuais para o recurso.Statement Type Descreve o tipo de instrução (SELECT, INSERT, UPDATE, ou 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 quebrar o ciclo de bloqueio. O thread escolhido e todos os seus 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 impasse não resolvido.executionstack Representa a pilha de chamadas Transact-SQL que está sendo executada no momento em que o deadlock ocorre.priority Representa a prioridade de bloqueio.logused Espaço de log usado pela tarefa.owner id O ID da transação que tem controle da solicitação.status Estado da tarefa. Para obter mais informações, consulte sys.dm_os_tasks.waitresource O recurso necessário para a tarefa.waittime Tempo em milissegundos à espera do recurso.schedulerid O agendador associado a esta tarefa. Consulte sys.dm_os_schedulers.hostname O nome da estação de trabalho.isolationlevel O nível de isolamento de transação atual.Xactid O ID da transação que tem controle da solicitação.currentdb A ID do banco de dados.lastbatchstarted A última vez que um processo de cliente iniciou a execução em lote.lastbatchcompleted A última vez que um processo de cliente concluiu a 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 habitualmente controladas por declarações SET como SET NOCOUNT e SET XACTABORT. Para obter mais informações, consulte @@OPTIONS.associatedObjectId Representa o ID HoBT (heap ou B-tree). |
| Atributos de recursos |
RID Identifica a única linha dentro de uma tabela na qual um bloqueio é mantido ou solicitado. 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.
OBJECT é representado como OBJECT: db_id:object_id. Por exemplo, TAB: 6:2009058193.KEY Identifica o intervalo de chaves dentro de um índice no qual um bloqueio é mantido ou solicitado. KEY é representado como KEY: db_id:hobt_id (valor de hash da chave do índice). Por exemplo, KEY: 6:72057594057457664 (350007a4d329).PAG Identifica o recurso de página no qual um bloqueio é mantido ou solicitado.
PAG é representado como PAG: db_id:file_id:page_no. Por exemplo, PAG: 6:1:20789.EXT Identifica a estrutura de extensão.
EXT é representado como EXT: db_id:file_id:extent_no. Por exemplo, EXT: 6:1:9.DB Identifica o bloqueio do banco de dados.
DB é representada de uma das seguintes formas:DB: db_idDB: db_id[BULK-OP-DB], que identifica o bloqueio do banco de dados obtido pelo backup do banco de dados.DB: db_id[BULK-OP-LOG], que identifica o bloqueio efetuado pelo backup de log.APP Identifica um bloqueio de aplicativo.
APP é representado como APP: lock_resource. Por exemplo, APP: Formf370f478.METADATA Representa os recursos de metadados envolvidos em um deadlock. Como METADATA tem muitos subrecursos, o valor retornado depende do subrecurso que está bloqueado. Por exemplo, METADATA.USER_TYPE retorna user_type_id = *integer_value*. Para obter mais informações sobre METADATA recursos e subrecursos, consulte sys.dm_tran_locks.HOBT Representa uma pilha ou árvore B envolvida em um impasse. |
Nenhum específico para esta bandeira de rastreamento. | Nenhum específico para esta bandeira de rastreamento. |
Exemplo do sinalizador de rastreamento 1204
O exemplo a seguir mostra a saída quando o sinalizador de rastreamento 1204 está ativado. Nesse caso, a tabela no Nó 1 é uma pilha sem índices e a tabela no Nó 2 é uma pilha com um índice não clusterizado. A chave de índice no Nó 2 está sendo atualizada quando ocorre o deadlock.
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. Nesse caso, uma tabela é uma pilha sem índices e a outra tabela é uma pilha com um índice não clusterizado. Na segunda tabela, a chave de índice está sendo atualizada quando ocorre o deadlock.
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 de 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 gráfico de deadlock está ativado.
Os recursos SQL Profiler e SQL Trace foram 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 SQL. Considere usar o evento de deadlock de Eventos Estendidos em vez de rastrear deadlocks no SQL Profiler.
Para obter mais informações sobre o evento deadlock, consulte Lock:Deadlock Event Class. Para obter mais informações sobre gráficos de deadlock do SQL Profiler, consulte Salvar gráficos de deadlock (SQL Server Profiler).
Eventos Estendidos fornecem equivalentes das classes de eventos do Rastreamento SQL. Para obter mais informações, consulte Exibir os eventos estendidos equivalentes a classes de eventos de rastreamento SQL. Eventos Estendidos são recomendados em vez de SQL Trace.
Lidar com bloqueios
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 forma:
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 envie consultas Transact-SQL 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 manipular o erro, o aplicativo poderá prosseguir sem saber que sua transação foi revertida.
A implementação de um manipulador de erros que deteta o erro 1205 permite que um aplicativo manipule deadlocks e tome medidas corretivas (por exemplo, reenviar automaticamente a consulta que estava envolvida no deadlock).
A aplicação deverá ser parada brevemente antes de voltar a enviar a consulta. Isso dá à outra transação envolvida no impasse a chance de concluir e liberar seus bloqueios. Randomizar a duração da pausa minimiza a probabilidade de o deadlock voltar a ocorrer 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.
Manuseie com TRY... CATCH
Você pode usar TRY... CATCH para lidar com impasses. O erro 1205 pode ser detetado pelo CATCH bloqueio.
Para obter mais informações, consulte Manipulando deadlocks.
Minimize os bloqueios
Embora os impasses não possam ser completamente evitados, seguir certas convenções de programação pode minimizar a possibilidade de gerar um impasse. Minimizar os impasses pode aumentar o débito de transações e reduzir a sobrecarga do sistema porque menos transações são:
- Revertidas, anulando todo o trabalho feito pela transação.
- Reenviadas pelas aplicações, porque foram revertidas aquando do impasse.
Para ajudar a minimizar os impasses:
- Aceda aos objetos na mesma ordem.
- Evite a interação do utilizador nas transações.
- Mantenha as transações curtas e num lote.
- Evite níveis de isolamento mais elevados, como
REPEATABLE READeSERIALIZABLEquando não for necessário. - Utilize um nível de isolamento baseado no controlo de versão de linha.
- Habilite a opção do
READ_COMMITTED_SNAPSHOTbanco de dados para usar o versionamento de linha em transações com oREAD COMMITTEDnível de isolamento. - Utilize transações com isolamento instantâneo.
- Habilite a opção do
- Utilize ligações vinculadas.
Acessar objetos na mesma ordem
Se todas as transações simultâneas acessarem objetos na mesma ordem, é menos provável que ocorram deadlocks. Por exemplo, se duas transações simultâneas obtiverem um bloqueio na Supplier tabela e depois na Part tabela, uma transação será bloqueada na Supplier tabela até que a outra transação seja concluída. Depois que a primeira transação é confirmada ou revertida, a segunda continua e um impasse não ocorre. O uso de procedimentos armazenados para todas as modificações de dados pode padronizar a ordem de acesso aos objetos.
Evite a interação do usuário nas transações
Evite transações que incluam interação do usuário, porque a velocidade de execução de lotes sem intervenção do usuário é muito mais rápida do que a velocidade na qual um usuário deve responder manualmente a consultas, como responder a um prompt para um parâmetro solicitado por um aplicativo. Isto degrada o débito do sistema porque quaisquer bloqueios processados pela transação são libertados apenas quando a transação é consolidada ou revertida. Mesmo que um impasse não ocorra, outras transações que acessam os mesmos recursos são bloqueadas enquanto aguardam a conclusão da transação.
Mantenha as transações curtas e em um lote
Um impasse ocorre tipicamente quando várias transações de longa duração são executadas em simultâneo na mesma base de dados. Quanto mais longa a transação, mais tempo os bloqueios exclusivos ou de atualização são mantidos, bloqueando outras atividades e levando a possíveis situações de impasse.
Manter as transações em um lote minimiza as viagens de ida e volta da rede durante uma transação, reduzindo possíveis atrasos na conclusão da transação devido ao processamento do cliente.
Evite níveis de isolamento mais elevados
Determine se uma transação pode ser executada em um nível de isolamento mais baixo. O uso READ COMMITTED permite que uma transação leia dados lidos anteriormente (mas não modificados) por outra transação sem esperar que a transação seja concluída.
READ COMMITTED mantém bloqueios compartilhados por um período mais curto do que um nível de isolamento mais alto, como SERIALIZABLE. Isso reduz a contenção de bloqueio.
Usar um nível de isolamento baseado em versionamento de linha
Quando a opção READ_COMMITTED_SNAPSHOT de banco de dados é definida como ON, uma transação em execução no nível de isolamento READ COMMITTED usa controle de versão de linha em vez de bloqueios compartilhados durante as operações de leitura.
Sugestão
A Microsoft recomenda o nível de isolamento baseado em controlo de versões de linha READ COMMITTED para todos os aplicativos, a menos que um aplicativo dependa do comportamento de bloqueio do nível de isolamento por bloqueio READ COMMITTED.
O isolamento de instantâneo também usa versionamento de linhas, que não utiliza bloqueios compartilhados nas operações de leitura. Antes que uma transação possa ser executada sob isolamento de instantâneo, a ALLOW_SNAPSHOT_ISOLATION opção de banco de dados deve ser definida ON.
Use níveis de isolamento baseados em controle de versão de linha para minimizar os bloqueios que podem ocorrer entre as operações de leitura e gravação.
Usar conexões acopladas
Usando conexões vinculadas, duas ou mais conexões abertas pelo mesmo aplicativo podem cooperar entre si. Todos os bloqueios adquiridos pelas conexões secundárias são mantidos como se tivessem sido adquiridos pela conexão primária e vice-versa. Portanto, eles não se bloqueiam.
Causar um impasse
Pode ser necessário causar um impasse para fins de aprendizagem ou demonstração.
O exemplo seguinte funciona no AdventureWorksLT2019 banco de dados de exemplo com o esquema e os dados padrão quando READ_COMMITTED_SNAPSHOT foi ativado. Para baixar este exemplo, visite as bases de dados de exemplo da AdventureWorks.
Para obter um exemplo que causa um deadlock quando o bloqueio otimizado está habilitado, consulte Bloqueio otimizado e deadlocks.
Para causar um impasse, você precisa conectar duas sessões ao banco de dados AdventureWorksLT2019. Referimo-nos a estas sessões como Sessão A e Sessão B. Você pode criar essas duas sessões criando duas janelas de consulta no SQL Server Management Studio (SSMS).
Na Sessão A, execute o seguinte lote. 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 qualificadas na tabela SalesLT.Product, que são então convertidas em bloqueios exclusivos (X). Deixamos a transação em aberto.
BEGIN TRANSACTION;
UPDATE SalesLT.Product
SET SellEndDate = SellEndDate + 1
WHERE Color = 'Red';
Agora, na Sessão B, execute o seguinte lote. Este código não inicia explicitamente uma transação. Em vez disso, ele opera em modo de transação de confirmação automática. Esta declaração atualiza a tabela SalesLT.ProductDescription. A atualização usa 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 esta atualização, a Sessão B necessita de bloqueios partilhados (S) nas linhas da tabela SalesLT.Product, incluindo as linhas bloqueadas pela Sessão A. A sessão B está bloqueada em SalesLT.Product.
Regressar à Sessão A. Execute a instrução a seguir UPDATE . Esta 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 declaração de atualização em Session A é bloqueada por Session B no SalesLT.ProductDescription.
Sessão A e Sessão B estão agora a bloquear-se mutuamente. Nenhuma transação pode prosseguir, pois cada uma 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 a bloquear-se mutuamente e que nenhuma delas pode progredir. Você vê um impasse ocorrer, com a Sessão A escolhida como a vítima do impasse. Sessão B é concluída com êxito. Uma mensagem de erro aparece na janela de consulta da Sessão A com texto semelhante ao exemplo a seguir:
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 impasse não for gerado, verifique se READ_COMMITTED_SNAPSHOT está habilitado no seu banco de dados de exemplo. Deadlocks podem ocorrer em qualquer configuração de banco de dados, mas este exemplo requer que READ_COMMITTED_SNAPSHOT esteja habilitado.
Você pode exibir os detalhes do deadlock no ring_buffer destino da sessão de evento, que está habilitada system_health e ativa por padrão no SQL Server e na Instância Gerenciada SQL do Azure. Considere a seguinte consulta:
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 dentro do Deadlock_XML SSMS, selecionando a célula que aparece como um hiperlink. Salve o resultado como .xdl ficheiro, feche e volte a abrir o .xdl ficheiro no SSMS para obter o gráfico visual de bloqueios. O gráfico de deadlock deve assemelhar-se à imagem seguinte.
Bloqueio otimizado e deadlocks
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 liberados 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 impasses é reduzida.
O exemplo anterior não causa um impasse quando o bloqueio otimizado está ativado, porque se baseia nos 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 seguintes lotes T-SQL, 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 possui 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 impasse.
O relatório de deadlock abreviado a seguir contém elementos e atributos específicos para o bloqueio otimizado. Sob cada recurso no relatório <resource-list> de deadlock, cada elemento <xactlock> relata os recursos subjacentes e informações de bloqueios 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 dos Eventos Estendidos
- sys.dm_tran_locks (Transact-SQL)
- Classe de evento do Deadlock Graph
- Impasses com nível de isolamento de leitura repetível
- Bloqueio: Classe de Evento de Cadeia de Bloqueio Mortal
- Lock:Deadlock Classe de evento
- DEFINIR DEADLOCK_PRIORITY (Transact-SQL)
- Analise e evite impasses 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)