web-dev-qa-db-ja.com

SQLトランザクションがデッドロックされました

あまり忙しくないSQLサーバーでこの種の例外が発生することがあります。

Transaction (Process ID 57) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.
Line number: 1
Error Number: 1205
Procedure: 
Server name: P01
Error Source: .Net SqlClient Data Provider
Error State: 47

再現できません。異なるクライアントから複数のクエリを同時に実行しようとしましたが、表示されませんでした。プロシージャ内またはトリガー内で発生したこの種の問題を処理する最良の方法は何ですか?つまり、トランザクションを再実行する方法は?

トリガーから呼び出されたプロシージャ内で例外が発生した場合の実行方法。これは、何らかのプロシージャによって作成された挿入によって呼び出されました(つまり、procedure01-> insert-> trigger-> procedure02!)

26
Piotr Salaciak

2つの観点から問題に取り組むことをお勧めします。

  1. トラップまたはキャッチデッドロックエラー。これにより、デッドロックの犠牲者として選択されたトランザクションを再実行できますSQL Serverデータベースエンジン。

  2. デッドロックイベントの原因を調べます。2つの方法のいずれかでこれを実行できます。SQL Server Profiler Traceを実行します。デッドロックイベントをキャッチして記録するか、いくつかの SQL ServerTrace Flags を有効にして、デッドロックイベントの詳細をSQL Serverエラーログに記録できます。 。

vast majorの場合、デッドロックイベントの原因を特定し、データベーススキーマの構造的変更または論理的デッドロックイベントに関与/責任を負うコードに変更します。

詳細については、以下をご覧ください。

私はあなたの質問に答えたことを望みますが、何らかの方法でさらにあなたを助けることができるかどうか知らせてください。

39
John Sansom

SQLプロファイラーで.trcファイルを確認できるように、デッドロックグラフイベントをキャプチャするサーバー側のSQLトレースを設定します。このようにして、デッドロックのトラブルシューティングを行うための場所を用意できます。以下のコードを提供しました。必要に応じてファイルパスを変更する必要があります。このスクリプトをSQLサーバーの起動時に実行するように構成することをお勧めします。

参考-さまざまなことがデッドロックを引き起こす可能性があり、そのうちの1つがインデックスを失っています。

declare @rc int
declare @TraceID int
declare @maxfilesize bigint
set @maxfilesize = 10 
declare @dtName nvarchar(50)
select @dtName=(N'I:\Trace_Logs\DeadLockTrace'+ convert(nvarchar(8),getdate(),112))


-- Please replace the text InsertFileNameHere, with an appropriate
-- filename prefixed by a path, e.g., c:\MyFolder\MyTrace. The .trc extension
-- will be appended to the filename automatically. If you are writing from
-- remote server to local drive, please use UNC path and make sure server has
-- write access to your network share

exec @rc = sp_trace_create @TraceID output, 2, @dtName, @maxfilesize, NULL ,365

if (@rc != 0) goto error

-- Client side File and Table cannot be scripted

-- Set the events
declare @on bit
set @on = 1
exec sp_trace_setevent @TraceID, 148, 11, @on
exec sp_trace_setevent @TraceID, 148, 51, @on
exec sp_trace_setevent @TraceID, 148, 4, @on
exec sp_trace_setevent @TraceID, 148, 12, @on
exec sp_trace_setevent @TraceID, 148, 14, @on
exec sp_trace_setevent @TraceID, 148, 26, @on
exec sp_trace_setevent @TraceID, 148, 60, @on
exec sp_trace_setevent @TraceID, 148, 64, @on
exec sp_trace_setevent @TraceID, 148, 1, @on
exec sp_trace_setevent @TraceID, 148, 41, @on
exec sp_trace_setevent @TraceID, 25, 7, @on
exec sp_trace_setevent @TraceID, 25, 15, @on
exec sp_trace_setevent @TraceID, 25, 55, @on
exec sp_trace_setevent @TraceID, 25, 8, @on
exec sp_trace_setevent @TraceID, 25, 32, @on
exec sp_trace_setevent @TraceID, 25, 56, @on
exec sp_trace_setevent @TraceID, 25, 64, @on
exec sp_trace_setevent @TraceID, 25, 1, @on
exec sp_trace_setevent @TraceID, 25, 9, @on
exec sp_trace_setevent @TraceID, 25, 25, @on
exec sp_trace_setevent @TraceID, 25, 41, @on
exec sp_trace_setevent @TraceID, 25, 49, @on
exec sp_trace_setevent @TraceID, 25, 57, @on
exec sp_trace_setevent @TraceID, 25, 2, @on
exec sp_trace_setevent @TraceID, 25, 10, @on
exec sp_trace_setevent @TraceID, 25, 26, @on
exec sp_trace_setevent @TraceID, 25, 58, @on
exec sp_trace_setevent @TraceID, 25, 3, @on
exec sp_trace_setevent @TraceID, 25, 11, @on
exec sp_trace_setevent @TraceID, 25, 35, @on
exec sp_trace_setevent @TraceID, 25, 51, @on
exec sp_trace_setevent @TraceID, 25, 4, @on
exec sp_trace_setevent @TraceID, 25, 12, @on
exec sp_trace_setevent @TraceID, 25, 52, @on
exec sp_trace_setevent @TraceID, 25, 60, @on
exec sp_trace_setevent @TraceID, 25, 13, @on
exec sp_trace_setevent @TraceID, 25, 6, @on
exec sp_trace_setevent @TraceID, 25, 14, @on
exec sp_trace_setevent @TraceID, 25, 22, @on
exec sp_trace_setevent @TraceID, 59, 55, @on
exec sp_trace_setevent @TraceID, 59, 32, @on
exec sp_trace_setevent @TraceID, 59, 56, @on
exec sp_trace_setevent @TraceID, 59, 64, @on
exec sp_trace_setevent @TraceID, 59, 1, @on
exec sp_trace_setevent @TraceID, 59, 21, @on
exec sp_trace_setevent @TraceID, 59, 25, @on
exec sp_trace_setevent @TraceID, 59, 41, @on
exec sp_trace_setevent @TraceID, 59, 49, @on
exec sp_trace_setevent @TraceID, 59, 57, @on
exec sp_trace_setevent @TraceID, 59, 2, @on
exec sp_trace_setevent @TraceID, 59, 14, @on
exec sp_trace_setevent @TraceID, 59, 22, @on
exec sp_trace_setevent @TraceID, 59, 26, @on
exec sp_trace_setevent @TraceID, 59, 58, @on
exec sp_trace_setevent @TraceID, 59, 3, @on
exec sp_trace_setevent @TraceID, 59, 35, @on
exec sp_trace_setevent @TraceID, 59, 51, @on
exec sp_trace_setevent @TraceID, 59, 4, @on
exec sp_trace_setevent @TraceID, 59, 12, @on
exec sp_trace_setevent @TraceID, 59, 52, @on
exec sp_trace_setevent @TraceID, 59, 60, @on

-- Set the Filters
declare @intfilter int
declare @bigintfilter bigint

-- Set the trace status to start
exec sp_trace_setstatus @TraceID, 1

-- display trace id for future references
select TraceID=@TraceID
goto finish

error: 
select ErrorCode=@rc

finish: 
go
5
Quantum Elf

Read Committed分離レベルを使用して、同様の問題を解決しました。

2
trueboroda

このエラーは次の方法で解決しました。

  1. SQL Serverを再起動します
  2. クエリの実行:

    使用[マスター] ALTER DATABASE name_database SET MULTI_USER WITH ROLLBACK IMMEDIATE

幸運を!

0
IT Vlogs