2011-07-21 22 views
8

Por lo que entiendo, los bloqueos de SQL ocurren cuando un SPID está ocupado procesando otra consulta y no se puede molestar en ejecutar otro porque está muy ocupado en este momento. SQL Server "aleatoriamente" selecciona una de las consultas para interbloquear los recursos solicitados y falla, lanzando una excepción.¿Por qué ocurren bloqueos en SQL Server?

Tengo una aplicación que ejecuta ~ 40 instancias y un servicio de fondo de Windows, todos los cuales están llegando a la misma base de datos. Estoy buscando reducir los interbloqueos para poder aumentar el número de subprocesos que puedo ejecutar simultáneamente.

  1. ¿Por qué no puede SQL Server simplemente poner en cola la nueva consulta y ejecutarla cuando tiene tiempo y los recursos están disponibles? La mayoría de lo que estoy haciendo puede esperar unos segundos en alguna ocasión.
  2. ¿Hay una manera de establecer de aislamiento de transacciones Nivel globalmente sin tener que especificar que en el inicio de cada nueva conexión/sesión?
+8

Su definición de 'deadlock' no es correcto. Normalmente SQL Server ** no ** permite que otras solicitudes esperen. Cuando se cierra una consulta porque detecta una condición de punto muerto, se debe a que el conjunto de consultas no se puede completar (nunca) y alguien tiene que perder. Creo que si lees un poco sobre lo que son los puntos muertos, estarás en una posición mucho mejor para obtener valor de una mejor pregunta –

+7

"Por lo que entiendo" ... el resto de ese párrafo es bastante incorrecto . – heisenberg

+1

Los bloqueos no tienen nada que ver con que el servidor esté demasiado ocupado como para atender una solicitud. Te sugiero que vuelvas a redactar tu pregunta o veas qué es realmente un punto muerto. – sqlvogel

Respuesta

18

Su comprensión de los puntos muertos no es correcto. Lo que has descrito es bloqueante. Es un error común equiparar los dos.

un interbloqueo cuando dos transacciones independientes, cada uno quieren diferentes recursos y ni dará a conocer la que tienen para que el otro puede funcionar. Es probable que sea más fácil para ilustrar:

SPID # 1 obtiene un bloqueo en el recurso A SPID # 2 consigue un bloqueo en el recurso B SPID # 1 ahora necesita un bloqueo en el recurso B con el fin de completar SPID # 2 ahora necesita un bloqueo en el recurso A para completar

SPID # 1 no puede completar (y por lo tanto recurso de liberación A) porque SPID # 2 lo tiene SPID # 2 no puede completar (y por lo tanto recurso de lanzamiento B) porque SPID # 1 tiene que

Dado que ni el SPID puede completar uno tiene que renunciar a (es decir, ser elegido por el servidor como sujeto del interbloqueo) y se producirá un error.

La mejor manera de evitarlos es mantener sus transacciones pequeñas (en cantidad de recursos necesarios) y rápidas.

+4

(+1) Imagine dos automóviles dirigiéndose el uno al otro en una carretera de un solo carril. Ambos necesitan el camino para continuar, pero obviamente ambos no pueden tenerlo a menos que un automóvil retroceda o desaparezca (es decir, 'rollback'). Ninguna cantidad de espera, memoria, disco, etc. puede ayudar –

+0

Los SPID en cuestión ni siquiera están ejecutando transacciones correctas; declaraciones simples de CRUD solamente. ¿Tengo que especificar no confirmado en cada uno? Generalmente, mi aplicación abrirá y cerrará una conexión para cada enunciado/consulta, a menos que tenga que agruparse en una fila. Pero se suman a través de n hilos yx usuarios. Cada declaración/consulta (de las que están en punto muerto) solo tarda unos 50-200ms en ejecutarse. – tsilb

+0

@tsilb puede encontrar esta herramienta ['aba_lockinfo'] (http://www.sommarskog.se/sqlutil/aba_lockinfo.html) muy útil –

3

interbloqueo es donde dos hilos de procesamiento están ambos retenidos por la otra (que puede ser más, pero dos es suficientemente compleja). Entonces, un hilo bloquea una tabla y luego solicita un bloqueo en otra mesa. la otra tabla está bloqueada por el segundo subproceso, que no puede avanzar porque está esperando un bloqueo en la primera tabla.

La razón de que uno de ellos tiene que ser expulsados ​​es que en un punto muerto, que nunca terminarán - ni hilo puede progresar en absoluto. La única respuesta es que uno se detenga para permitir que el otro lo complete.

La solución para reducir los interbloqueos en el tipo de situación de la que está hablando puede ser rediseñar la solución. Si puede asegurarse de que se produzca menos bloqueo, tendrá menos puntos muertos.

1

Los bloqueos se producen porque, dos transacciones simultáneas pueden solaparse e bloquear diferentes recursos, ambos requeridos por la otra transacción para finalizar.

Imaginemos: 1 - cerraduras de una transacción fila1 2 - bloqueos de transacciones B fila2 3 - Transacción Una intenta bloquear fila1, y, a causa de la cerradura anterior, SQL Server espera 4 - transacción B intenta bloquear row2, y, debido al bloqueo anterior, el servidor SQL espera

Por lo tanto, el servidor SQL debe elegir en la transacción, elimínela y permita que la otra continúe.

Esta imagen ilustrates muy bien esta situación: http://www.eupodiatamatando.com/wp-content/uploads/2008/01/deadlocknajkcomafarialibh3.jpg

Cuestiones relacionadas