Estendendo a resposta de Marcos ...
Quando ocorre um evento de tempo limite do cliente (.net CommandTimeout, por exemplo), o cliente envia um "ABORT" ao SQL Server. O SQL Server simplesmente abandona o processamento da consulta. Nenhuma transação é revertida, nenhum bloqueio é liberado.
Agora, a conexão é retornada ao pool de conexões, portanto não está fechada no SQL Server. Se isso acontecer (via KILL ou reinicialização do cliente etc), as transações + bloqueios serão apagadas. Observe que sp_reset_connection não os limpa ou não, mesmo que seja anunciado para isso
Esse detrito do aborto irá bloquear outros processos.
A maneira de fazer o SQL Server limpar transações + bloqueios no tempo limite do cliente (estritamente, eventos ABORT) é usar SET XACT_ABORT ON.
Você pode verificar se isso abre duas janelas de consulta no SSMS:
Janela 1:
No menu Query..Query Options, defina um tempo limite de 5 segundos e execute
BEGIN TRAN
UPDATE sometable WITH (TABLOCKX) SET foo = foo WHERE 1 = 0;
WAITFOR DELAY '00:00:10' -- just has to be longer then timeout
Janela 2, isso esperará para sempre (ou atingirá o tempo limite)
SELECT * FROM sometable
SET XACT_ABORT ON também tem efeitos colaterais interessantes:
- @@ TRANCOUNT é definido como zero na reversão implícita, mas o erro 266 é suprimido (isso acontece se @@ TRANCOUNT for diferente na entrada e na saída de um processo armazenado)
- XACT_STATE será -1 (está "condenado")
A combinação disso significa que você não pode usar SAVEPOINTS (embora não me lembre do comportamento exato) para confirmações / reversões parciais. O que combina comigo
Links SO no SET XACT_ABORT:
Em procs armazenados aninhados:
Em sp_reset_connection:
Estou respondendo com hesitação, pois não há informações suficientes em sua descrição do problema para ter 100% de certeza de que este é o melhor conselho. "Trava ou gera uma exceção" sugere que a origem do problema não foi entendida corretamente, portanto, prossiga com cuidado.
A solução mais simples para isso é provavelmente
SET XACT_ABORT ON
.XACT_ABORT
determina se o SQL Server reverterá uma transação no caso de um erro em tempo de execução. O padrãoSET XACT_ABORT OFF
reverterá apenas a instrução que causou um erro, deixando qualquer transação pai aberta.O efeito colateral "pegadinha" da configuração padrão é que um tempo limite pode causar exatamente o mesmo problema, uma transação aberta que é da responsabilidade do cliente manipular e reverter. Se o cliente não tentar / capturar / reverter, a transação permanecerá aberta até que seja atendida (e cito @gbn) a ultra-violência
KILL <spid>
.Os artigos frequentemente citados de Erland Sommarskog sobre tratamento de erros no SQL Server contêm todo o plano de fundo e estratégia necessários para lidar com esses cenários e muito mais.
Editar (seguinte comentário): Para identificar transações abertas, sp_whoisactive é provavelmente o recurso mais completo.
fonte