データベース操作におけるデッドロックは避けられません。この記事では、デッドロックがどのように発生するかについて説明するつもりはありません。SQL Server 2005 による新しい解決策が考えられます。
次の SQL ステートメントを 2 つの異なる接続に配置し、5 秒以内に同時に実行すると、デッドロックが発生します。
Northwind を使用する
トランを開始する
Orders(CustomerId) の値 ('ALFKI') に挿入する
遅延 '00:00:05' を待つ
select * from Orders where CustomerId = 'ALFKI'
コミット
print 'end tran'
SQLサーバーがデッドロックに対処する方法は、そのうちの 1 つを犠牲にして例外をスローし、トランザクションをロールバックすることです。 SQL Server 2000 では、ステートメントで例外が発生すると、T-SQL は実行を継続せず、上記の犠牲接続では print 'end tran' ステートメントは実行されないため、T- を使用するのは困難です。 SQL Server 2000 の SQL。デッドロックのさらなる処理が提供されます。
現在は異なります。SQL Server 2005 は T-SQL で例外をキャプチャできるため、デッドロックに対処する方法が提供されます。
次の try...catch はデッドロックを解決するために使用されます。
SET :00:05'
select * from Orders where CustomerId = 'ALFKI'
commit
Break
end try
begin catch
rollback
waitfor遅延 '00:00:03'
set @r = @r 1
続行
終了キャッチ
終了
解決策はもちろん再試行ですが、エラーをキャッチすることが前提条件です。ロールバック後の waitfor は必須です。競合が発生した後は、さまざまな要件に合わせて @retry の回数を調整する必要があります。
しかし今、私たちは新たな問題に直面しています。エラーが 3 回以上発生すると、例外はスローされなくなります。 SQL Server 2005 には、例外をスローできる RaiseError ステートメントがありますが、元の例外を直接スローすることはできないため、発生するエラーを再定義する必要があります。
declare @r int
set @r = 1
while @r <= 3
begin
begin tran
begin try
Orders(CustomerId) の値('ALFKI') に挿入
waitfor遅延 '00:00:05'
select * from Orders where CustomerId = ' ALFKI'
http://www.bkjia.com/PHPjc/630998.html
www.bkjia.com
true