Identificar sesiones bloqueadoras y bloqueadas

Señal o problema observado

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

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

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;

Parámetros o permisos

Las DMV tienen alcance de servidor. Normalmente se necesita VIEW SERVER STATE; desde SQL Server 2022, VIEW SERVER PERFORMANCE STATE. Con MARS pueden existir varias conexiones o solicitudes para una sesión y aparecer más de una combinación.

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 antes de decidir cualquier intervención.