特定のデッドロックシナリオを証明するためにテストケースを設定しており、何が起こっているのかについての洞察が必要です。ヒープテーブルは、HeapTableと呼ばれています。このテーブルは、2つのトランザクションによって同時に更新されます。
トランザクション1:
BEGIN TRAN
UPDATE HeapTable
SET FirstName = 'Dylan'
WHERE FirstName = 'Ovidiu';
WAITFOR DELAY '00:00:15';
UPDATE HeapTable
SET FirstName = 'Bob'
WHERE FirstName = 'Thierry';
ROLLBACK TRANSACTION
トランザクション2:
BEGIN TRAN
UPDATE HeapTable
SET FirstName = 'Pierre'
WHERE FirstName = 'Michael';
ROLLBACK TRAN
最初にトランザクション1を起動し、その後にトランザクション2を続けます。予想どおり、トランザクション1はいくつかの排他的ロックといくつかの意図的な排他的ロックを要求します。トランザクション2が受信され、同じRIDで更新ロックを要求します。
spid dbid ObjId IndId Type Resource Mode Status
55 5 711673583 0 RID 1:24336:10 X GRANT
57 5 711673583 0 RID 1:24336:10 U WAIT
2番目のトランザクションが同じRIDで更新ロックを要求するのを見て驚いたのは、これが単一のレコードを指し、両方の更新ステートメントが異なるデータを処理するためだと思ったからです。代わりに、ページレベルでの競合を予想していました。
トランザクション1の2番目の更新がトランザクション2で開始されると、デッドロックの犠牲者と見なされ、トランザクション2のロールバックとトランザクション1の完了が発生します。
別のレコードを更新しているにもかかわらず、2番目のトランザクションが同じRIDで更新ロックを必要とする理由を誰かが説明してもらえますか?
これを修正する方法を知っています(たとえば、インデックスを使用)。私は修正プログラムを探しているのではなく、ヒープ内の異なるレコードを処理する2つの更新が同じRIDをロックする理由についての説明を実際に探しています。コミットされた読み取り分離を使用しています。テーブルに非クラスター化インデックスはありません。