2010-06-25 17 views
48

Veo cómo desactivar el nivel de fila y el bloqueo de nivel de página en SQL Server, pero no encuentro una forma de obligar a SQL Server a utilizar el bloqueo de nivel de fila. ¿Hay alguna manera de forzar a SQL Server a usar el bloqueo de nivel de fila y NO usar el bloqueo de nivel de página?¿Es posible forzar el bloqueo de nivel de fila en SQL Server?

+1

La pregunta principal sería: ¿por qué ** ** en la tierra le gustaría hacer esto en la primera ¿¿lugar?? –

+3

Tengo dos sentencias SQL que se ejecutan en un interbloqueo, lo que no esperaba. Ver: http://stackoverflow.com/questions/3112699/how-can-i-avoid-a-deadlock-between-these-two-sql-statements – Elan

+0

@marc_s Tenía la misma necesidad. ¿Sabes por qué? Tengo una sp que necesita ejecutarse en paralelo y donde tengo un código para que varias tablas se modifiquen por una gran cantidad de filas. No tengo idea de por qué esto no debe considerarse una necesidad válida y natural. El problema es que causa un punto muerto en SQL Server ... – Mashrur

Respuesta

30

Usted puede utilizar la sugerencia ROWLOCK, pero que yo sepa SQL pueden decidir una escalada que si se ejecuta bajo de recursos

From the doco:

ROWLOCK Especifica que la fila cerraduras son tomada cuando la página o bloqueos de tabla son ordinariamente tomadas. Cuando se especifica en transacciones que operan en el nivel de aislamiento SNAPSHOT , los bloqueos de fila no son tomados a menos que ROWLOCK se combine con otros consejos de tabla que requieren bloqueos, tales como UPDLOCK y HOLDLOCK.

y

bloqueo insinúa ROWLOCK, UPDLOCK, Y XLOCK que adquieren bloqueos a nivel de fila puede colocar cerraduras de las claves de índice en lugar de los filas de datos reales. Por ejemplo, si una tabla tiene un índice no agrupado, y una instrucción SELECT utilizando una sugerencia de bloqueo se manejado por un índice de cobertura, una cerradura se adquirió en la clave de índice en el cubriendo índice en lugar de en los datos fila en la mesa base.

And finally esto da una explicación muy detallada acerca de la extensión de bloqueo en SQL Server 2005 que fue cambiado en SQL Server 2008.

Existe también, la misma en profundidad: Locking in The Database Engine (en los libros en línea)

por lo tanto, en general

UPDATE 
Employees WITH (ROWLOCK) 
SET Name='Mr Bean' 
WHERE Age>93 

debería estar bien, pero dependiendo de los índices y de carga en el servidor puede terminar la escalada a un bloqueo de página.

+9

solo para agregar, en el servidor sql 2008+ puede DESACTIVAR efectivamente la escalada de bloqueo con 'ALTER TABLE tableName SET (LOCK_ESCALATION = DISABLE)' –

+0

[basado en sus comentarios a Remus Rusanu] significa que no hay nada que podamos hacer para bloquear una fila en todo, ¿cómo lo hace Oracle? – bjan

+0

@bjan no estoy seguro, en general, la naturaleza de snapshot de Oracle significa que es menos propenso a este tipo de bloqueo de todas formas. En general, evitaría cualquier sugerencia de rowlock. Casi nunca se necesita. –

13

Utilice la cláusula allow_page_locks de ALTER/CREATE INDEX:

ALTER INDEX indexname ON tablename SET (ALLOW_PAGE_LOCKS = OFF); 
+4

Una nota importante es que esto puede escalar a un bloqueo de tabla si se ejecuta bajo en recursos –

+8

@Sam: Detalles;) Verdad en publicidad: ** nunca ** desactivaría esto en mi base de datos. La solución siempre es diseñar correctamente el esquema y las consultas para que los escaneos (que son los culpables de la escalada) no ocurran para empezar ... –

+0

totalmente de acuerdo ... es muy raro que necesite este tipo de cortes y luego terminas mordiéndote de todos modos –

Cuestiones relacionadas