Enviar pergunta
Conteúdo

Publicado em 15 de junho de 2026

Deadlock em Alta Volumetria: Diagnóstico de Baixo Impacto com Extended Events e DMVs

Sistemas travando por deadlocks? Descubra como diagnosticar e resolver conflitos de concorrência em produção de alta volumetria sem sacrificar o throughput.

Em ambientes de alta volumetria transacional (OLTP), a concorrência é uma constante. No entanto, quando essa concorrência evolui para deadlocks (impasses fatais), o impacto deixa de ser meramente técnico e passa a ser financeiro. Transações abortadas geram retentativas na camada de aplicação, aumentam a latência das APIs, degradam a experiência do usuário e, no limite, causam perda de receita direta.

Para diretores e gerentes de TI, o diagnóstico desses cenários costuma vir acompanhado de uma recomendação cara: fazer o upgrade do tier de banco de dados (escala vertical). Como engenheiro de dados sênior e tech lead, sei que na maioria das vezes o problema não é a falta de hardware ou vCores no Azure SQL, mas sim a arquitetura de acesso aos dados e a falta de visibilidade fina sobre os conflitos de travas.

Neste artigo, vamos analisar um deadlock sob alta carga e aprender a diagnosticá-lo utilizando ferramentas nativas de baixíssimo impacto: Extended Events (XEvents) e Dynamic Management Views (DMVs), preservando o throughput da sua operação.


O Cenário de Negócio e o Impacto Financeiro

Imagine uma plataforma de e-commerce ou um sistema de liquidação financeira processando milhares de requisições por segundo. Um deadlock ocorre quando a Transação A possui uma trava no Recurso 1 e solicita uma trava no Recurso 2, enquanto a Transação B possui uma trava no Recurso 2 e solicita uma trava no Recurso 1.

O motor do SQL Server (o Lock Monitor) detecta o ciclo de dependência a cada 5 segundos (ou menos, se houver recorrência) e escolhe uma das transações como vítima, aplicando um ROLLBACK compulsório e retornando o famoso Error 1205.

O impacto operacional disso é severo:

  1. Desperdício de Recursos (FinOps): CPU e I/O foram gastos para processar a transação vítima até o ponto do corte. Todo esse esforço é jogado fora e o custo de computação na nuvem é duplicado na retentativa.
  2. Efeito Bola de Neve: A aplicação, ao receber o erro 1205, tende a reexecutar a query imediatamente, empilhando ainda mais requisições sobre um ecossistema que já está operando sob estresse de travas.

O Erro Clássico do Diagnóstico: O Perigo dos Trace Flags

No passado, a resposta padrão para diagnosticar deadlocks era ativar globalmente os Trace Flags 1204 ou 1222 (DBCC TRACEON(1222, -1)).

Não faça isso em produção de alta volumetria. O TF 1222 força o SQL Server a despejar o grafo do deadlock detalhado diretamente no Error Log. Em ambientes com centenas de deadlocks por minuto, a escrita síncrona no log do servidor atua como um gargalo de I/O massivo, degradando drasticamente o desempenho global do motor. Precisamos de telemetria assíncrona e cirúrgica.


Uma abordagem com Extended Events (XEvents) de Baixo Impacto

Os Extended Events são integrados nativamente ao motor do SQL Server e operam de forma assíncrona com consumo de memória extremamente reduzido. A sessão padrão system_health já captura eventos de deadlock por padrão, mas em ambientes de alta rotação, os buffers dessa sessão podem girar muito rápido, sobrescrevendo os dados históricos que você precisa analisar.

Abaixo, apresento a definição de uma sessão customizada de Extended Events focada exclusivamente em capturar o grafo do deadlock com o menor overhead possível.

1. Criando a Sessão de Captura

CREATE EVENT SESSION [Capture_Deadlocks_UltraLight] ON SERVER 
ADD EVENT sqlserver.xml_deadlock_report
ADD TARGET package0.event_file(SET filename=N'Capture_Deadlocks_UltraLight.xel', max_file_size=(5), max_rollover_files=(4))
WITH (
    MAX_MEMORY            = 4096 KB,
    EVENT_RETENTION_MODE  = ALLOW_MULTIPLE_EVENT_LOSS,
    MAX_DISPATCH_LATENCY  = 30 SECONDS,
    MAX_EVENT_SIZE        = 0 KB,
    MEMORY_PARTITION_MODE = NONE,
    TRACK_CAUSALITY       = OFF,
    STARTUP_STATE         = ON
);
GO

-- Ativando a sessão
ALTER EVENT SESSION [Capture_Deadlocks_UltraLight] ON SERVER STATE = START;
GO

Por que essa configuração é segura para produção?

  • MAX_MEMORY = 4096 KB: Aloca uma quantidade ínfima de memória para o buffer.

  • EVENT_RETENTION_MODE = ALLOW_MULTIPLE_EVENT_LOSS: Garante que, se o servidor entrar em estresse extremo, o SQL Server priorizará o processamento das transações dos clientes em detrimento da gravação do log de auditoria. Ele prefere perder um evento a travar a aplicação.

  • MAX_DISPATCH_LATENCY = 30 SECONDS: O envio dos dados do buffer para o arquivo .xel em disco ocorre de forma assíncrona a cada 30 segundos, minimizando o impacto no fluxo principal de I/O.

2. Lendo os Grafos de Deadlock Coletados via T-SQL

Uma vez capturado o incidente, você não precisa copiar arquivos do servidor para a sua máquina. Podemos extrair e parsear o XML diretamente via DMVs:

SELECT 
    CAST(event_data.value('(event/data[@name="xml_report"]/value)[1]', 'varchar(max)') AS XML) AS DeadlockGraph,
    event_data.value('(event/@timestamp)[1]', 'datetime2') AS EventTime
FROM (
    SELECT 
        CAST(event_data AS XML) AS event_data
    FROM sys.fn_xe_file_target_read_file('Capture_Deadlocks_UltraLight*.xel', NULL, NULL, NULL)
) AS InsideTable
ORDER BY EventTime DESC;

Ao clicar no nó XML retornado na coluna DeadlockGraph dentro do SQL Server Management Studio (SSMS), o grafo gráfico abrirá na sua tela, revelando os objetos envolvidos, os tipos de travas solicitadas (ex: Exclusive Locks X vs Update Locks U) e as linhas de código exatas que causaram a colisão.

Investigação Complementar via DMVs: Identificando Concorrência Atual

Enquanto o deadlock é um evento consumado (onde uma transação já morreu), os Locks Prolongados (Blocks) costumam preceder ou acompanhar esses episódios. Para mapear o cenário antes do colapso, execute esta consulta baseada na sys.dm_exec_requests e sys.dm_os_waiting_tasks:

SELECT 
    r.session_id          AS [Sessao_Bloqueada],
    r.blocking_session_id AS [Sessao_Bloqueadora],
    r.wait_time           AS [Tempo_Espera_MS],
    r.wait_type           AS [Tipo_Espera],
    t.text                AS [Query_Bloqueada],
    p.query_plan          AS [Plano_Execucao_Bloqueado]

FROM sys.dm_exec_requests                         r
CROSS APPLY sys.dm_exec_sql_text(r.sql_handle)    t
CROSS APPLY sys.dm_exec_query_plan(r.plan_handle) p

WHERE r.blocking_session_id <> 0;
GO

Soluções Arquiteturais Robustas (Evitando Remendos)

Identificado o grafo do deadlock, a solução nunca deve ser espalhar SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED ou hints de (NOLOCK) pelo sistema. O uso indiscriminado de leituras sujas quebra a consistência do negócio, gerando duplicidade em relatórios financeiros e comportamentos erráticos no software.

As abordagens mais eficientes incluem:

  1. Ordenação Estrita de Objetos: Garanta que todas as frentes da aplicação acessem as tabelas exatamente na mesma ordem cronológica. Se a API de Vendas atualiza a Tabela_A e depois a Tabela_B, o processo batch de Integração não pode atualizar a Tabela_B e depois a Tabela_A.

  2. Habilitação do RCSI (Read Committed Snapshot Isolation): Uma das estratégias FinOps e arquiteturais mais poderosas no SQL Server. Ao ativar o RCSI, os comandos de leitura (SELECT) passam a ler versões históricas das linhas guardadas no tempdb (ou no próprio banco, se for Azure SQL), eliminando o conflito onde leitores bloqueiam escritores e escritores bloqueiam leitores.

    ALTER DATABASE [BACKOFFICE_DB] SET READ_COMMITTED_SNAPSHOT ON WITH ROLLBACK IMMEDIATE;
  3. Snapshot Isolation (SI): Abordagem com isolamento individual de transações. Não altera o comportamento padrão do banco. Os desenvolvedores precisam habilitá-lo globalmente e invocá-lo explicitamente apenas nas transações ou queries específicas que exigem esse rigor.

    -- Transação 1
    BEGIN TRANSACTION;
    
        SET TRANSACTION ISOLATION LEVEL SNAPSHOT;
         
        SELECT Product_Name FROM Products WHERE Product_ID = 1;
        -- Result: Product_Name = 'Dorflex'
        
        -- Transação 2 (executada simultaneamente)
        BEGIN TRANSACTION;
        
            UPDATE Products SET Product_Name = 'Dipirona + Citrato de Orfenadrina + Cafeína' WHERE Product_ID = 1;
        
        COMMIT;
        
        -- Transação 1 (continua)
    
        SELECT Product_Name FROM Products WHERE Product_ID = 1;
        -- Result: Product_Name = 'Dorflex' (WARNING: leitura realizada a partir do snapshot)
    
    COMMIT;
  4. Indexação Cirúrgica: Queries sem índices de cobertura apropriados realizam Index Scans ou Table Scans, travando a tabela inteira ou páginas completas desnecessariamente, expandindo a área de contato das travas. Um índice bem desenhado faz a query realizar um Index Seek focado apenas nas linhas estritas do predicado, minimizando a chance de colisão.

Ressalvas Importantes para Ambientes de Alta Performance

  • Crescimento do TempDB com RCSI: Ao adotar o Read Committed Snapshot Isolation, o tempdb passará a armazenar o versionamento de linhas (Version Store). Certifique-se de monitorar o crescimento e a latência de I/O do tempdb antes de realizar a virada em produção. Em sistemas muito transacionais, os arquivos do tempdb devem estar idealmente alocados em discos de ultra performance (SSD/NVMe) e fracionados corretamente por core de CPU para evitar contenção de páginas PFS/GAM.

  • Volume de Arquivos do XEvents: Embora a estratégia de Extended Events apresentada seja extremamente leve, a leitura constante de arquivos .xel muito grandes via sys.fn_xe_file_target_read_file realiza processamento de XML e consome CPU. Execute a query de leitura apenas durante as janelas de análise técnica, e evite embutir essa leitura de disco em dashboards automatizados de monitoramento que rodam de minuto em minuto.

Conclusão

Deadlocks em cenários de alta volumetria são o sintoma visível de que a escala técnica colidiu com os limites do design de código implementado. Tratar esse problema apenas adicionando mais capacidade de hardware é uma solução paliativa, ineficiente do ponto de vista de FinOps e com prazo de validade curto.

Ao dominar o uso de Extended Events e DMVs, é possível isolar as assinaturas exatas dos processos concorrentes com impacto praticamente nulo na produção. A eliminação real desses incidentes passa pelo redesenho de índices, refinamento da ordem transacional ou adoção de modelos modernos de isolamento baseados em versionamento de linhas, garantindo a sustentabilidade da arquitetura e a estabilidade financeira da operação.

Foto de perfil de William Marques
Networking & Colaboração

Vamos trocar experiências sobre dados, performance e soluções?

Se você se interessa por engenharia de dados, performance de bancos de dados e arquitetura de soluções, vamos nos conectar! Estou sempre aberto a discussões técnicas, colaboração em projetos e troca de experiências.

// Conteúdos Recomendados