Realmente tengo problemas para rastrear algunos bloqueos que estamos experimentando.
El estado del SPID de bloqueo de raíz es 'durmiendo', el cmd es 'EN ESPERA DE MANDO' y el sqltext
es SET TRANSACTION ISOLATION LEVEL READ COMMITTED
.
Cuando veo el informe Top Transactions by Blocked Transactions Count, la instrucción SQL de bloqueo es '-'.
He realizado un seguimiento en el SQL y cuando ocurre el bloqueo, rastreando el SPID de bloqueo de raíz, pero realmente no me ha llevado a ninguna parte. La última declaración de rastreo es la misma que la sqltext
anterior SET TRANSACTION ISOLATION LEVEL READ COMMITTED
.
Verifiqué todos los procedimientos almacenados relacionados que puedo encontrar para asegurarme de que tengan sentencias TRY / CATCH BEGIN TRAN / COMMIT TRAN / ROLLBACK TRAN (utilizamos procedimientos almacenados para todo, por lo que no se ejecutan sentencias independientes). Este problema acaba de comenzar a suceder en las últimas 24 horas y nadie afirma haber realizado ningún cambio en el sistema.
Solución: uno de nuestros procedimientos almacenados que rara vez se usaba tenía un error con una inserción (el número de columnas no coincidía), pero aún estamos confundidos sobre lo que estaba sucediendo exactamente.
Al observar toda la información de rastreo, la instrucción EXEC para este procedimiento almacenado se enumeraba a veces, pero NUNCA justo antes de que ocurriera el BLOQUEO en el SPID de bloqueo. Parecía que cuando comenzaba a bloquear, la traza no registraba la ejecución de la misma (ni ninguna de las declaraciones dentro de ella). Sin embargo, hay otros momentos en que la traza registró su ejecución y no se produjo ningún bloqueo.
El informe de error del procedimiento almacenado provino de un usuario, y pude encontrar múltiples declaraciones EXEC en las trazas y ejecutarlas en SSMS. En ningún momento cuando los ejecuté tuvimos algún bloqueo o se bloquearon. Funcionaron como se esperaba (el bloque catch se disparó y retiró la transacción después del error). Después de resolver la solución del procedimiento almacenado, no hemos vuelto a ver el problema.
fuente
Respuestas:
Según los comentarios, supongo que tuvo un tiempo de espera de comando del lado del cliente que ha cancelado la consulta SQL. Esto no revierte la transacción porque la conexión permanece abierta en SQL Server debido a la agrupación de conexiones.
Por lo tanto, debe usar SET XACT_ABORT ON o agregar algún código de reversión de cliente
Vea SQL Server Transaction Timeout para todos los detalles sangrientos
fuente
Use most_recent_sql_handle en sys.dm_exec_connections para ver la última instrucción que se ejecutó.
También verifique si hay transacciones abiertas para ese spid
fuente
DBCC INPUTBUFFER(spid)
para ver el último SQL ejecutado.¿Has intentado usar sp_whoisactive de Adam Machanic ? Hay una opción para obtener el comando externo para ver si realmente está dentro de un proceso. Podría ser que la aplicación mantenga abierta una transacción en lugar de confirmarla. Intente mirar DBCC OPENTRAN también.
fuente