Identificar sesiones bloqueadoras y bloqueadas
Una solicitud permanece suspendida y muestra un identificador en blocking_session_id. Necesitamos saber quién espera, qué sesión está delante y qué texto podemos inspeccionar en ambos extremos.
Qué necesitamos distinguir
Un bloqueo es la espera que ocurre cuando una sesión conserva una protección sobre un recurso que otra necesita. La bloqueadora posee o conserva esa protección; la bloqueada espera poder continuar.
Mostraremos la solicitud bloqueada y la sesión señalada como bloqueadora. Si esta última no tiene una solicitud activa, recuperaremos el texto más reciente de su conexión como pista, dejando claro que puede no ser la instrucción que abrió la transacción o adquirió el bloqueo.
Consulta
/*
Antes de ejecutar:
Revisa los permisos y los límites antes de ejecutar la consulta.
Confirma el alcance, la base activa y el costo posible de la consulta.
Captura evidencia en varios momentos antes de atribuir una causa.
Este script es de observación. No aplica correcciones ni modifica datos.
*/
SET NOCOUNT ON;
GO
-- Consulta
SELECT
rb.session_id AS SesionBloqueada,
rb.blocking_session_id AS SesionBloqueadora,
sb.login_name AS LoginBloqueado,
sb.host_name AS EquipoBloqueado,
sb.program_name AS AplicacionBloqueada,
sr.login_name AS LoginBloqueador,
sr.host_name AS EquipoBloqueador,
sr.program_name AS AplicacionBloqueadora,
rb.wait_type AS TipoEspera,
rb.wait_time AS EsperaMilisegundos,
rb.wait_resource AS RecursoEspera,
SUBSTRING
(
tb.text,
(rb.statement_start_offset / 2) + 1,
((CASE rb.statement_end_offset
WHEN -1 THEN DATALENGTH(tb.text)
ELSE rb.statement_end_offset
END - rb.statement_start_offset) / 2) + 1
) AS SentenciaBloqueada,
tr.text AS TextoActualORecienteBloqueador
FROM sys.dm_exec_requests AS rb
INNER JOIN sys.dm_exec_sessions AS sb
ON sb.session_id = rb.session_id
LEFT JOIN sys.dm_exec_sessions AS sr
ON sr.session_id = rb.blocking_session_id
LEFT JOIN sys.dm_exec_requests AS rr
ON rr.session_id = rb.blocking_session_id
LEFT JOIN sys.dm_exec_connections AS cr
ON cr.session_id = rb.blocking_session_id
OUTER APPLY sys.dm_exec_sql_text(rb.sql_handle) AS tb
OUTER APPLY sys.dm_exec_sql_text
(
COALESCE(rr.sql_handle, cr.most_recent_sql_handle)
) AS tr
WHERE rb.blocking_session_id IS NOT NULL
AND rb.blocking_session_id <> 0
ORDER BY
rb.wait_time DESC,
rb.session_id;
GO
Parámetros o permisos
Las vistas de administración dinámica (DMV) consultadas tienen alcance de servidor y exponen estado que cambia mientras el motor trabaja. Normalmente se necesita VIEW SERVER STATE; desde SQL Server 2022, VIEW SERVER PERFORMANCE STATE. Con Multiple Active Result Sets (MARS), una misma conexión puede mantener más de una solicitud activa y aparecer en varias combinaciones. SQL Server también utiliza valores negativos en blocking_session_id para propietarios que no pueden representarse como una sesión normal, como ciertas transacciones distribuidas o estados internos. En esos casos no habrá datos de login ni texto para el supuesto bloqueador.
Cómo leer el resultado
Cada fila parte de una solicitud que espera. SesionBloqueadora es el identificador comunicado por SQL Server, mientras que RecursoEspera describe el recurso en el formato de la DMV; ninguno explica todavía por qué el bloqueo se prolongó. Si la sesión bloqueadora está activa, TextoActualORecienteBloqueador suele corresponder a su solicitud actual. Si está inactiva, el texto procede de most_recent_sql_handle y solo muestra lo último asociado a la conexión.
Qué conclusión sí permite obtener
Permite relacionar solicitudes bloqueadas con el identificador de su bloqueador y reunir datos de sesión, espera y texto disponibles durante la captura.
Qué conclusión todavía no permite obtener
No prueba que el texto reciente haya adquirido el bloqueo ni que terminar la sesión sea una acción segura. Tampoco muestra por sí sola toda la cadena ni el alcance de una posible reversión.
Siguiente comprobación razonable
Construye la cadena completa de bloqueo. Si la cabeza está inactiva, revisa las transacciones abiertas y las sesiones inactivas con una transacción antes de decidir cualquier intervención.