Pregunta Causa de un proceso siendo una víctima de bloqueo


Tengo un proceso con un Select que tarda mucho tiempo en terminar, del orden de 5 a 10 minutos.
Actualmente no estoy usando NOLOCK como una pista para el motor de base de datos MS SQL.
Al mismo tiempo, tenemos otro proceso que realiza actualizaciones e inserta en la misma base de datos y en las mismas tablas.
 El primer proceso ha comenzado, recientemente para terminar prematuramente con un mensaje

SQLEXCEPTION: Transacción se estancó en los recursos de bloqueo con otro proceso y se ha elegido como la víctima de interbloqueo.

Este primer proceso se ejecuta en otros sitios en condiciones idénticas, pero con bases de datos más pequeñas y, por lo tanto, la declaración seleccionada en cuestión toma un período de tiempo mucho más corto (del orden de 30 segundos más o menos). En estos otros sitios, no recibo el mensaje de interbloqueo en estos otros sitios. Tampoco recibí este mensaje en el sitio que está teniendo el problema inicialmente, pero, supongo, como la base de datos ha crecido, creo que debo haber cruzado cierto umbral. Aquí están mis preguntas:

  1. ¿Podría el tiempo necesario para que se ejecute una transacción que el proceso asociado sea más probable que se marque como víctima de interbloqueo?
  2. Si ejecuto la selección con una sugerencia NOLOCK, ¿esto eliminará el problema?
  3. Sospecho que un campo de fecha y hora que se comprueba como parte de la cláusula WHERE en la instrucción select está causando el tiempo de búsqueda lenta. ¿Puedo crear un índice basado en este campo? ¿Es aconsejable?

76
2017-12-05 18:52


origen


Respuestas:


P1: ¿Podría el tiempo necesario para que se ejecute una transacción que el proceso asociado sea más probable que se marque como una víctima de interbloqueo.

No. El SELECT es la víctima porque solo tenía datos leídos, por lo tanto, la transacción un costo menor asociado con él, por lo que se elige como la víctima:

De forma predeterminada, el motor de base de datos elige como la víctima del interbloqueo el   sesión ejecutando la transacción que es menos costoso para revertir.   Alternativamente, un usuario puede especificar la prioridad de las sesiones en un   situación de estancamiento utilizando el SET DEADLOCK_PRIORITY declaración.   DEADLOCK_PRIORITY se puede establecer en LOW, NORMAL o HIGH o alternativamente   se puede establecer en cualquier valor entero en el rango (-10 a 10).

Q2. Si ejecuto la selección con una sugerencia NOLOCK, ¿esto eliminará el problema?

No. Por varias razones:

Q3. Sospecho que un campo de fecha y hora que se comprueba como parte de la cláusula WHERE en la instrucción select está causando el tiempo de búsqueda lenta. ¿Puedo crear un índice basado en este campo? ¿Es aconsejable?

Probablemente. Es muy probable que la causa del estancamiento sea una base de datos pobremente indexada. Las consultas de 10 minutos son aceptables en condiciones tan limitadas, que estoy 100% seguro en su caso. no aceptable.

Con un 99% de confianza declaro que su interbloqueo está cubierto por un escaneo de tabla grande que está en conflicto con las actualizaciones. Comience capturando el gráfico de interbloqueo para analizar la causa Es muy probable que deba optimizar el esquema de su base de datos. Antes de hacer cualquier modificación, lea este tema Diseñando Índices y los subartículos.


96
2017-12-05 19:13



Así es como realmente ocurrió este problema particular de interbloqueo y cómo realmente se resolvió. Esta es una base de datos bastante activa con 130,000 transacciones diarias. Los índices en las tablas en esta base de datos se agruparon originalmente. El cliente nos solicitó que no indexemos los índices. Tan pronto como lo hicimos, comenzó el bloqueo. Cuando restablecimos los índices como agrupados, el bloqueo se detuvo.


9
2017-12-14 22:54



Las respuestas aquí valen la pena intentarlo, pero también debes revisar tu código. Específicamente, lea la respuesta de Polyfun aquí: ¿Cómo deshacerse del punto muerto en una aplicación SQL Server 2005 y C #?

Explica el problema de concurrencia y cómo el uso de "with (updlock)" en sus consultas puede corregir su situación de interbloqueo, dependiendo realmente de lo que está haciendo su código. Si su código sigue este patrón, es probable que sea una mejor solución, antes de recurrir a lecturas sucias, etc.


2
2017-09-28 05:14