Warum verursacht diese Abfrage einen Deadlock?
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)
Deadlock-Grafik hinzugefügt:
<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>
HINZUGEFÜGT:
Vielen Dank an Sankar für den Artikel, der Lösungen zur Vermeidung dieser Art von Deadlock enthält:
- Entfernen Sie unnötige Spalten aus der Projektion des Lesers, damit er den Clustered-Index nicht nachschlagen muss
- Fügen Sie dem nicht gruppierten Index die erforderlichen Spalten als enthaltene Spalten hinzu, damit der Index abgedeckt wird, damit der Leser den gruppierten Index nicht nachschlagen muss
- Vermeiden Sie Aktualisierungen, bei denen der nicht gruppierte Index beibehalten werden muss
sql-server-2008
deadlock
garik
quelle
quelle
Antworten:
Es sieht für mich so aus, als würden Sie versuchen, ein SELECT und ein UPDATE in derselben Anweisung und in derselben Tabelle auszuführen.
Das SELECT hält eine gemeinsame Sperre für die Werte im IX_system_Queue_DirectionByStatus-Index, und das UPDATE muss diese Sperren freigeben, bevor es seine exklusive Sperre erhält, die den Primärschlüssel aktualisiert (der vermutlich gruppiert ist und auch Teil des IX_system_Queue_DirectionByStatus-Schlüsselwert).
Ich vermute jedenfalls, dass diese Abfrage nur dann erfolgreich ist, wenn die ausgewählten und aktualisierten Indexwerte nicht in Konflikt stehen. Ist es bei jeder Ausführung ein Deadlock? (Ich gehe davon aus, dass dies der Fall ist.)
Hier ist ein Link, der Deadlocks ausführlicher erklärt: http://sqlblog.com/blogs/jonathan_kehayias/archive/2008/07/30/the-anatomy-of-a-deadlock.aspx
quelle
Ich erwarte nicht, dass Sie diesen Beitrag als Antwort markieren, sondern hier weitere Informationen von anderen SQL Server-Experten zu diesem Thema teilen.
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/
quelle