アプリケーションの一部は、トランザクション分離レベル REPEATABLE READ で接続を開いた後、ビジネス ロジックに従ってテーブルを更新します。まれに、この操作が別の接続を開き、同じレコードをデフォルト値にリセットしようとするアプリケーションの別の部分と一致する場合があります。次のエラーが表示されます
Msg 1205, Level 13, State 45, Line 7
Transaction (Process ID 60) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.
次の例を使用して問題を再現できると思います。
1.
create table Accounts
(
id int identity(1,1),
Name varchar(50),
Amount decimal
)
2.
insert into Accounts (Name,Amount) values ('ABC',5000)
insert into Accounts (Name,Amount) values ('WXY',4000)
insert into Accounts (Name,Amount) values ('XYZ',4500)
3.
分離レベルが REPEATABLE READ のロング トランザクションを開始する
Set transaction isolation level REPEATABLE READ
begin tran
declare @var int
select @var=amount
from Accounts
where id=1
waitfor delay '0:0:10'
if @var > 4000
update accounts
set amount = amount -100;
Commit
4.
上記の Step.3 がまだ実行されている間。別の接続で別のトランザクションを開始する
Begin tran
update accounts
set Amount = 5000
where id = 1
commit tran
ステップ 3 で開始されたトランザクションは最終的に完了しますが、ステップ 4 で開始されたトランザクションは失敗し、次のエラー メッセージが表示されます。
Msg 1205, Level 13, State 45, Line 7
Transaction (Process ID 60) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.
ステップ4で最終的にトランザクションを実行できるようにするためのオプションは何ですか。アイデアは、レコードをデフォルト値にリセットできるようにすることであり、この場合、他のトランザクションで実行されているものはすべてオーバーライドする必要があります。両方のトランザクションが同時でない場合、問題はありません。