2009-03-19 22 views
32

Toda la documentación sobre interbloqueos de SQL Server habla sobre el escenario en el que la operación 1 bloquea el recurso A luego intenta acceder al recurso B y la operación 2 bloquea el recurso B e intenta acceder al recurso ASQL Server interbloqueos entre seleccionar/actualizar o múltiples selecciones

Sin embargo, a menudo veo deadlocks entre una selección y una actualización o incluso entre selecciones múltiples en algunas de nuestras aplicaciones ocupadas. Encuentro que algunos de los puntos más finos de la salida de trazabilidad del punto muerto son bastante impenetrables, pero realmente me gustaría entender qué puede causar un punto muerto entre dos operaciones individuales. Sin duda, si un select tiene un bloqueo de lectura, la actualización debería esperar antes de obtener un bloqueo exclusivo y viceversa.

Esto está sucediendo en SQL Server 2005 no es que creo que esto marque la diferencia.

Respuesta

11

una vez que ha agregado un marcador un buen artículo sobre Advanced SQL Server locking en SQL-Server-Performance.com. Ese artículo va más allá de la clásica situación de punto muerto que ha mencionado y podría brindarle una idea de su problema.

0

Usted debe leer sobre aislamiento de la transacción: http://msdn.microsoft.com/en-us/library/ms173763.aspx

+0

Entiendo acerca de los niveles de aislamiento, los interbloqueos anteriores se pueden resolver haciendo que la lectura de selección no esté comprometida PERO, ¿por qué una lectura que comienza ANTES de una actualización termina en un punto muerto con esa actualización usando read commit? –

1

Lea correctamente las transacciones y los niveles de aislamiento: para un trabajo un tanto denso pero bastante exhaustivo y neutral en cuanto a tecnología, vea Principles of Transaction Processing. Me estremeció el mundo (¡y me dio bastantes dolores de cabeza!).

No estoy seguro de con qué tiene problemas o qué nivel de aislamiento está utilizando. Pero considere esto: para todo lo que sabe el motor de base de datos, si lee en una transacción, ¿cómo puede saber si va a escribir más adelante? Los altos niveles de aislamiento requieren bloqueo cada vez que se realiza una lectura, posiblemente en toda la tabla para proteger contra lecturas fantasmas, ya que los datos pueden afectar una escritura más adelante.

¿Desea que la base de datos espere arbitrariamente un bloqueo exclusivo de sus datos? Observe sus niveles de aislamiento en todo momento y si está ejecutando innecesariamente una serie de lecturas como una transacción aislada. No siempre es fácil determinar lo sucio lee usted puede tolerar, aunque ...

+2

Creo que la pregunta de los carteles fue más específica que una queja general sobre los niveles de aislamiento puede curar. – eckes

+0

No describiría exactamente a PoTP como una diatriba. Rob pidió ayuda específicamente para comprender la transaccionalidad, y pareció tener problemas para entender las compensaciones involucradas. Si señalar literatura útil es despotricar, ¡entonces probablemente estoy espumeando en la boca todo el tiempo! YMMV. –

5

Cerraduras entre consultas individuales pueden ocurrir a medida que bloquear filas individuales, no toda la tabla:

La consulta de actualización recibe una actualización bloqueo en unas pocas filas en una tabla, y la consulta de selección obtiene un bloqueo de lectura en algunas otras filas de la tabla. La consulta de actualización intenta obtener un bloqueo de actualización en las filas que se leen de forma bloqueada, y la consulta de selección intenta obtener un bloqueo de lectura en las filas que están actualizadas.

Puede complicarse aún más con los bloqueos en escalamiento, es decir, la base de datos decide que hay demasiadas filas bloqueadas por una transacción para que se escalen y bloqueen una sección de la tabla o toda la tabla. Esto significa que el bloqueo puede afectar a las filas que no están directamente involucradas en la consulta.

19

Esto puede suceder porque una selección realiza un bloqueo en dos índices diferentes, mientras tanto una actualización bloquea los mismos índices en el orden opuesto. El selecto necesita dos índices porque el primer índice no cubre todas las columnas a las que necesita acceder; la actualización necesita dos índices porque si actualiza la columna de clave de un índice, debe bloquearla.

http://blogs.msdn.com/bartd/archive/2006/09/25/770928.aspx tiene una explicación fantástica. Las soluciones sugeridas incluyen agregar un índice que cubra todas las columnas que necesita la selección, cambiar al aislamiento de instantáneas u obligar explícitamente a la selección a tomar un bloqueo de actualización que normalmente no necesitaría.

12

Me sorprende que nadie haya mencionado la sugerencia de bloqueo WITH (UPDLOCK). Es muy útil si tiene puntos muertos que involucren, p. dos pares select-insert que se ejecutan en paralelo.

En SQL Server, si emite las selecciones con WITH (UPDLOCK), la segunda selección esperará hasta que termine la primera selección. De lo contrario, obtienen bloqueos compartidos, y cuando simultáneamente intentan actualizar a bloqueos exclusivos, se estancan.

+0

'Rolf Kristensen' explicó' WITH (UPDLOCK) 'perfectamente en su respuesta. – Mahmoodvcs

4

Supongo que el enunciado de selección adquiere un bloqueo de lectura, cuando usted viene con la instrucción de actualización, entonces necesita actualizar a un bloqueo de escritura.

La actualización a un bloqueo de escritura requiere que se eliminen todos los demás bloqueos de lectura (Sus transacciones de selección se completan). Pero si otro proceso ya tiene la brillante idea de actualizar a un bloqueo de escritura, entonces de repente tiene dos procesos esperando el lanzamiento del bloqueo de lectura, para que puedan obtener el bloqueo de escritura.

Si utiliza select-for-update (UPDLOCK), obtendrá un bloqueo de escritura desde el principio y luego no tendrá el problema de interbloqueo.

Cuestiones relacionadas