最近、一部のコードを C# から SQL (SQL Server 2005) に移動して、同時実行の問題を回避しようとしました。ただし、SQL ではデッドロックが発生しています。デッドロックを取得する手順を再作成することはできませんが、SQL トレースでキャプチャできました。
テーブルにはトリガーはありませんが、検索をサポートするためのインデックスがいくつかあります。
トレースによると、デッドロックは、同じレコードで同じ update ステートメントを実行している 2 人のユーザーによって引き起こされています。
UPDATE myTable
SET
col2 = @var2 + col2
,col3 = CASE WHEN (@Var2 <= 0 OR @Var2 + Col2 <= 0)
THEN Col3
ELSE
CONVERT
(
dbo.MoneyInfo,
@var3 + ':' + @Var4 + ':' + @Var5
)
END
OUTPUT INSERTED.Col0,
Inserted.Col2,
Inserted.Col3
WHERE Col0 = @Var1
dbo.MoneyInfo
カスタム CLR 型です。テーブルは次のようになります。
create table myTable
(
col0 int,
col1 int,
col2 decimal(18,2),
col3 dbo.MoneyInfo
)
Col0 はクラスター化されていない主キー (PK_Stock)、col1 はクラスター化されたインデックス (IX_Item) です。
これは、トレースからのデッドロック グラフです。
まったく同じストアド プロシージャ ステートメントを実行している 2 人のユーザーが、同じステートメントでデッドロックに陥る可能性があることを理解できません。最初の接続がレコードをロックして、2 番目の接続が使用可能になるまで待機するように強制するべきではありませんか? このデッドロックの原因を調べることができるものは他にありますか? OUTPUT ステートメントが原因でしょうか。