このクエリがデッドロックを引き起こすのはなぜですか?
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)
追加されたデッドロックグラフ:
<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>
ADDED:
ありがとう Sankar この種のデッドロックを回避する方法を解決する記事がある記事:
同じステートメントで同じテーブルに対してSELECTとUPDATEを実行しようとしているように見えます。
SELECTはIX_system_Queue_DirectionByStatusインデックス内の値に共有ロックを保持しており、UPDATEはそれらのロックを解放してから、主キーを更新する排他ロックを取得する必要があります(これはクラスター化されており、 IX_system_Queue_DirectionByStatusキー値)。
とにかく、私のクエリは、このクエリは、選択して更新しているインデックス値が競合していないというまれな機会でのみ成功すると思います。あなたが実行するたびにデッドロックしていますか(私はそうだと思います)。
デッドロックを詳細に説明するリンクは次のとおりです。 http://sqlblog.com/blogs/jonathan_kehayias/archive/2008/07/30/the-anatomy-of-a-deadlock.aspx
この投稿に回答のマークを付けることは期待していませんが、このトピックに関する他のSQL Serverエキスパートがここで詳細情報を共有しています。