Consultar o sys.dm_tran_locks
DMV nos mostra quais sessões (SPIDs) estão mantendo bloqueios em recursos como tabela, página e linha.
Para cada bloqueio adquirido, existe alguma maneira de determinar qual instrução SQL (excluir, inserir, atualizar ou selecionar) causou esse bloqueio?
Eu sei que a most_recent_query_handle
coluna do sys.dm_exec_connections
DMV nos dá o texto da última consulta executada, mas várias vezes outras consultas foram executadas antes na mesma sessão (SPID) e ainda estão mantendo bloqueios.
Já utilizo o sp_whoisactive
procedimento (de Adam Machanic) e ele mostra apenas a consulta que está no buffer de entrada no momento (pense DBCC INPUTBUFFER @spid
), que nem sempre (e no meu caso geralmente nunca) é a consulta que adquiriu o bloqueio.
Por exemplo:
- abrir transação/sessão
- exec uma instrução (que mantém um bloqueio em um recurso)
- exec outra instrução na mesma sessão
- abra outra transação/sessão e tente modificar o recurso bloqueado na etapa 2.
O sp_whoisactive
procedimento apontará a instrução na etapa 3, que não é a responsável pelo bloqueio e, portanto, não é útil.
Essa pergunta surgiu ao fazer uma análise usando o recurso Blocked Process Reports , para encontrar a causa raiz dos cenários de bloqueio na produção. Cada transação executa várias consultas e, na maioria das vezes, a última (que é mostrada no buffer de entrada no BPR) raramente é a que mantém o bloqueio.
Eu tenho uma pergunta de acompanhamento: Estrutura para identificar efetivamente as consultas de bloqueio