" Bloqueo de escala " es cómo SQL maneja el bloqueo para actualizaciones grandes. Cuando SQL va a cambiar muchas filas, es más eficiente que el motor de la base de datos tome menos bloqueos más grandes (por ejemplo, toda la tabla) en lugar de bloquear muchas cosas más pequeñas (por ejemplo, bloqueos de filas).
Pero esto puede ser problemático cuando tiene una tabla enorme, porque bloquear una tabla completa puede bloquear otras consultas durante mucho tiempo. Esa es la compensación: muchos bloqueos de granularidad pequeña son más lentos que menos (o uno) bloqueos de grano grueso, y tener múltiples consultas bloqueando diferentes partes de una tabla crea la posibilidad de un punto muerto si un proceso está esperando a otro.
Hay una opción de nivel de tabla LOCK_ESCALATION
, nueva en SQL 2008, que permite el control de la escalada de bloqueo. El valor predeterminado "TABLE" permite que los bloqueos se escalen hasta el nivel de la tabla. DISABLE evita la escalada de bloqueo a toda la tabla en la mayoría de los casos. AUTO permite bloqueos de tabla, excepto si la tabla está particionada, en cuyo caso los bloqueos solo se hacen hasta el nivel de partición. Vea esta publicación de blog para más información.
Sospecho que el IDE agrega esta configuración al volver a crear una tabla porque TABLE es el valor predeterminado en SQL 2008. Tenga en cuenta que LOCK_ESCALATION no es compatible con SQL 2005, por lo que deberá quitarlo si intenta ejecutar el script en un Instancia de 2005. Además, dado que TABLE es el valor predeterminado, puede eliminar esa línea de forma segura cuando vuelva a ejecutar su script.
También tenga en cuenta que, en SQL 2005 antes de que esta configuración estuviera presente, todos los bloqueos podían escalar al nivel de la tabla; en otras palabras, "TABLE" era la única configuración en SQL 2005.
CREATE TABLE
porque la tabla aún no existe, por lo que no hay nada que bloquear.ALTER TABLE
declaraciones separadas . PrimeroALTER TABLE ADD column
, luegoGO
, luego segundoALTER TABLE SET LOCK_ESCALATION=TABLE
, luego segundoGO
. Entonces,LOCK_ESCALATION
se establece después de agregar la columna. ¿Cuál es el punto de configurarlo después del hecho? Estas dosALTER TABLE
declaraciones están envueltas en una transacción, pero aún así la columna se agrega antes de queLOCK_ESCALATION
se establezca. Creo que profundizaré un poco más y escribiré otra respuesta.Puede verificar si necesita incluir la declaración LOCK_ESCALATION en su script comparando este valor antes y después de ejecutar la parte principal de su script:
En mi caso, alterar la tabla para eliminar o agregar una restricción no parece modificar este valor.
fuente
La respuesta de Justin Grant explica qué
LOCK_ESCALATION
hace la configuración en general, pero pierde un detalle importante y no explica por qué SSMS genera el código que lo establece. Especialmente, parece muy extraño queLOCK_ESCALATION
se establezca como una última declaración en el script.Hice algunas pruebas y aquí está mi comprensión de lo que está sucediendo aquí.
Version corta
La
ALTER TABLE
declaración que agrega, elimina o altera una columna implícitamente toma un bloqueo de modificación de esquema (SCH-M) en la tabla, que no tiene nada que ver con laLOCK_ESCALATION
configuración de una tabla.LOCK_ESCALATION
afecta el comportamiento de bloqueo durante las instrucciones DML (INSERT
,UPDATE
,DELETE
, etc.), no durante las sentencias DDL (ALTER
). El bloqueo SCH-M siempre es un bloqueo de todo el objeto de la base de datos, tabla en este ejemplo.Esto es probablemente de donde viene la confusión.
SSMS agrega la
ALTER TABLE <TableName> SET (LOCK_ESCALATION = ...)
declaración a su script en todos los casos, incluso cuando no es necesario. En los casos en que se necesita esta declaración, se agrega para preservar la configuración actual de la tabla, no para bloquear la tabla de alguna manera específica durante el cambio en el esquema de la tabla que ocurre en ese script.En otras palabras, la tabla se bloquea con el bloqueo SCH-M en la primera
ALTER TABLE ALTER COLUMN
instrucción mientras se realiza todo el trabajo de cambiar el esquema de la tabla. La últimaALTER TABLE SET LOCK_ESCALATION
declaración no lo afecta. Afecta a las declaraciones DML futuro sólo (INSERT
,UPDATE
,DELETE
, etc.) para esa tabla.A primera vista, parece que
SET LOCK_ESCALATION = TABLE
tiene algo que ver con el hecho de que estamos cambiando toda la tabla (estamos alterando su esquema aquí), pero es engañoso.Versión larga
Cuando se modifica la tabla en algunos casos, SSMS genera un script que recrea la tabla completa y en algunos casos más simples (como agregar o soltar una columna) el script no vuelve a crear la tabla.
Tomemos esta tabla de muestra como ejemplo:
Cada tabla tiene una
LOCK_ESCALATION
configuración, que está configuradaTABLE
de manera predeterminada. Vamos a cambiarlo aquí:Ahora, si trato de cambiar el
Col1
tipo en el diseñador de tablas SSMS, SSMS genera un script que recrea la tabla completa:Puede ver arriba que se establece
LOCK_ESCALATION
para la tabla recién creada. SSMS lo hace para preservar la configuración actual de la tabla. SSMS genera esta línea, incluso si el valor actual de la configuración es elTABLE
valor predeterminado . Solo para ser seguro y explícito y evitar posibles problemas futuros si en el futuro este valor predeterminado cambia, supongo. Esto tiene sentido.En este ejemplo, es realmente necesario generar la
SET LOCK_ESCALATION
declaración, porque la tabla se crea de nuevo y su configuración debe conservarse.Si trato de hacer un cambio simple en la tabla usando el diseñador de tablas SSMS, como agregar una nueva columna, entonces SSMS genera un script que no vuelve a crear la tabla:
Como puede ver, todavía agrega la
ALTER TABLE SET LOCK_ESCALATION
declaración, aunque en este caso no es necesaria en absoluto. El primeroALTER TABLE ... ADD
no cambia la configuración actual. Supongo que los desarrolladores de SSMS decidieron que no vale la pena intentar determinar en qué casos estoALTER TABLE SET LOCK_ESCALATION
declaración es redundante y generarla siempre, solo para estar seguros. No hay daño en agregar esta declaración cada vez.Una vez más, la
LOCK_ESCALATION
configuración de toda la tabla es irrelevante, mientras que el esquema de la tabla cambia a través de laALTER TABLE
instrucción.LOCK_ESCALATION
la configuración solo afecta el comportamiento de bloqueo de las declaraciones DML, comoUPDATE
.Finalmente, una cita de
ALTER TABLE
, enfatiza la mía:fuente