¿Por qué esta consulta causa un punto muerto?
UPDATE TOP(1) system_Queue SET
[StatusID] = 2,
@ID = InternalID
WHERE InternalID IN (
SELECT TOP 1
InternalID FROM system_Queue
WHERE IsOutGoing = @IsOutGoing AND StatusID = 1
ORDER BY MessageID ASC, InternalID ASC)
Gráfico de punto muerto agregado:
<keylock hobtid="72057594236436480" dbid="9" objectname="Z.dbo.system_Queue" indexname="PK_system_Queue" id="lock5b25cc80" mode="X" associatedObjectId="72057594236436480">
<owner-list>
<owner id="processc6fe40" mode="X"/>
</owner-list>
<waiter-list>
<waiter id="processc7b8e8" mode="S" requestType="wait"/>
</waiter-list>
</keylock>
<keylock hobtid="72057594405453824" dbid="9" objectname="Z.dbo.system_Queue" indexname="IX_system_Queue_DirectionByStatus" id="lock48cf3180" mode="S" associatedObjectId="72057594405453824">
<owner-list>
<owner id="processc7b8e8" mode="S"/>
</owner-list>
<waiter-list>
<waiter id="processc6fe40" mode="X" requestType="wait"/>
</waiter-list>
</keylock>
ADICIONAL:
Gracias Sankar por el artículo que tiene soluciones para evitar este tipo de punto muerto:
- eliminar columnas innecesarias de la proyección del lector para que no tenga que buscar el índice agrupado
- agregue las columnas requeridas como columnas contenidas al índice no agrupado para hacer que el índice cubra, nuevamente para que el lector no tenga que buscar el índice agrupado
- evitar actualizaciones que tengan que mantener el índice no agrupado
sql-server-2008
deadlock
Garik
fuente
fuente
Respuestas:
Me parece que está intentando hacer una SELECCIÓN y una ACTUALIZACIÓN en la misma declaración y en la misma tabla.
SELECT mantiene un bloqueo compartido en los valores dentro del índice IX_system_Queue_DirectionByStatus, y la ACTUALIZACIÓN necesita que esos bloqueos se liberen antes de que pueda obtener su bloqueo exclusivo que actualizará la clave principal (que supongo que está agrupada y también es parte del IX_system_Queue_DirectionByStatus valor clave).
De todos modos, supongo que esta consulta solo tendrá éxito en la rara posibilidad de que los valores de índice que está seleccionando y actualizando no entren en conflicto. ¿Es un punto muerto cada vez que ejecutas (supongo que lo sería).
Aquí hay un enlace que explica los puntos muertos con más detalle: http://sqlblog.com/blogs/jonathan_kehayias/archive/2008/07/30/the-anatomy-of-a-deadlock.aspx
fuente
No espero que marque esta publicación como respuesta, pero comparte más información aquí por otros expertos de SQL Server sobre este tema.
http://sqlblog.com/blogs/alexander_kuznetsov/archive/2009/01/01/reproducing-deadlocks-involving-only-one-table.aspx
http://rusanu.com/2009/05/16/readwrite-deadlock/
fuente