SQL Server en la práctica

Escalamiento de bloqueos: encuentre la causa

Distinga los bloqueos de intención de los bloqueos de tabla y diseñe lotes que liberen recursos entre transacciones independientes.

Un proceso de mantenimiento modifica unos miles de filas y, de repente, otras solicitudes empiezan a esperar. El escalamiento de bloqueos es una causa posible, pero observar un bloqueo de tabla no lo demuestra. Primero identifique el bloqueo incompatible que impide avanzar y la transacción propietaria.

Interpretar la evidencia

Un bloqueo de intención exclusiva sobre un objeto es normal cuando se modifican sus filas. Indica bloqueos de nivel inferior; no significa que todos los lectores estén excluidos. Un bloqueo compartido o exclusivo de tabla tiene otras reglas de compatibilidad. Confundir IX con X puede orientar toda la investigación hacia una solución equivocada.

La consulta muestra bloqueos de objeto concedidos y pendientes en la base actual. Su alcance es limitado: pueden existir bloqueos de clave, página, esquema o aplicación fuera de este resultado. Los permisos de diagnóstico dependen de la versión y deben asignarse mediante el rol de monitorización establecido.

SELECT request_session_id, resource_type, request_mode,
       request_status, resource_associated_entity_id
FROM sys.dm_tran_locks
WHERE resource_database_id = DB_ID()
  AND resource_type = 'OBJECT';

Relacione las sesiones con la cadena de bloqueo y las instrucciones activas. Capture el evento extendido lock_escalation cuando sospeche esa causa. Un bloqueo X actual no revela si nació por escalamiento, un hint explícito u otra operación. El evento aporta la historia que no puede proporcionar una instantánea.

No trate un número concreto de filas como frontera garantizada. Las filas no equivalen a bloqueos. Índices, acceso, aislamiento y presión de memoria afectan al consumo. ROWLOCK no garantiza la ausencia de escalamiento. Deshabilitarlo puede cambiar un problema de concurrencia por agotamiento de recursos.

Crear límites transaccionales reales

El objetivo es reducir los recursos retenidos simultáneamente. Una instrucción pequeña dentro de una transacción que engloba toda la repetición sigue acumulando bloqueos. Los commits independientes proporcionan los puntos de liberación. Compruebe si el cliente, procedimiento llamador o planificador introduce una transacción exterior.

Este ejercicio crea datos temporales y los modifica mediante instrucciones confirmadas independientemente. Exige no tener una transacción abierta y mantener IMPLICIT_TRANSACTIONS desactivado. El tamaño del lote muestra el mecanismo, no una recomendación universal para producción.

IF @@TRANCOUNT <> 0 OR (@@OPTIONS & 2) = 2
    THROW 50000, 'Use autocommit with no open transaction.', 1;
CREATE TABLE #Work (Id int PRIMARY KEY, Done bit NOT NULL);
INSERT #Work
SELECT TOP (10000) ROW_NUMBER() OVER (ORDER BY (SELECT NULL)), 0
FROM sys.all_objects AS a CROSS JOIN sys.all_objects AS b;
DECLARE @changed int = 1;
WHILE @changed > 0
BEGIN
    ;WITH batch AS
    (SELECT TOP (500) Id, Done FROM #Work
     WHERE Done = 0 ORDER BY Id)
    UPDATE batch SET Done = 1;
    SET @changed = @@ROWCOUNT;
END;
SELECT COUNT(*) AS Remaining FROM #Work WHERE Done = 0;

La selección ordenada por clave hace comprensible el avance. En una tabla real, el predicado necesita un acceso eficiente. Un lote puede cambiar 500 filas y leer millones para encontrarlas. Revise filas leídas, lecturas lógicas, esperas y duración transaccional además de @@ROWCOUNT.

Probar concurrencia y reinicios

Ejecute el trabajo con lectores y escritores representativos. Compare las solicitudes más lentas, eventos de escalamiento y generación de log antes y después. Un mantenimiento algo más lento puede ser preferible si las solicitudes cumplen su objetivo de respuesta. Por otra parte, miles de commits diminutos introducen costes que también deben medirse.

Los commits independientes cambian el comportamiento ante fallos. Una cancelación deja una operación parcialmente terminada. El criterio de elegibilidad debe permitir reanudar sin omitir trabajo, y cualquier registro de avance debe confirmarse con los cambios correspondientes. Si se requiere atomicidad sobre todo el conjunto, introducir lotes cambia el contrato de negocio.

Revise también desencadenadores, cascadas, replicación y transporte del log hacia grupos de disponibilidad. Estos componentes pueden multiplicar el trabajo de una actualización aparentemente pequeña. Incluya una interrupción deliberada en la prueba y compruebe que reanudar no repite efectos externos ni pierde filas pendientes. La solución debe explicar el bloqueador original, reducir los recursos relevantes y preservar la semántica necesaria. Que desaparezca el evento de escalamiento no demuestra por sí solo que la aplicación funcione mejor.

Referencias técnicas: Microsoft Learn: Lock escalation · Microsoft Learn: Lock diagnostics.

Pregunta sobre este artículo

¿Tiene alguna pregunta sobre este tema?

Cuéntenos qué está evaluando o dónde tiene dificultades. Le responderemos con una recomendación práctica.

Inquiries are not enabled in this preview.

Hacer una pregunta sobre este artículo