web-dev-qa-db-ja.com

プロセスがデッドロックの被害者になる原因

5〜10分程度で完了するまでに時間がかかるSelectを使用したプロセスがあります。
現在、MS SQLデータベースエンジンへのヒントとしてNOLOCKを使用していません。
同時に、同じデータベースと同じテーブルに対して更新と挿入を行う別のプロセスがあります。
最初のプロセスが開始されました。最近、メッセージで途中で終了します

SQLEXCEPTION:トランザクションは別のプロセスでロックリソースでデッドロックされ、デッドロックの犠牲者として選択されました。

この最初のプロセスは、同じ条件で他のサイトで実行されますが、データベースが小さいため、問題のselectステートメントの所要時間ははるかに短くなります(30秒程度)。これらの他のサイトでは、これらの他のサイトでデッドロックメッセージが表示されません。最初に問題が発生しているサイトでもこのメッセージは表示されませんでしたが、データベースが大きくなったため、何らかのしきい値を超えたに違いないと考えています。私の質問は次のとおりです。

  1. トランザクションの実行にかかる時間により、関連するプロセスがデッドロックの被害者としてフラグを立てられる可能性が高くなります。
  2. NOLOCKヒントを使用して選択を実行すると、問題は解決しますか?
  3. Select文のWHERE句の一部としてチェックされるdatetimeフィールドが、ルックアップ時間を遅くしていると思われます。このフィールドに基づいてインデックスを作成できますか?お勧めですか?
90
Elliott

この特定のデッドロック問題が実際にどのように発生し、実際にどのように解決されたかを次に示します。これは、毎日130Kのトランザクションが発生しているかなりアクティブなデータベースです。このデータベースのテーブルのインデックスは、もともとクラスター化されていました。クライアントは、インデックスを非クラスター化するように要求しました。すぐに、デッドロックが始まりました。クラスター化されたインデックスを再確立すると、デッドロックが停止しました。

11
Elliott

ここでの回答は試してみる価値がありますが、コードも確認する必要があります。具体的には、ここでPolyfunの答えを読んでください: SQL Server 2005およびC#アプリケーションでデッドロックを取り除く方法?

同時実行の問題と、クエリで「with(updlock)」を使用するとデッドロック状態がどのように修正されるかを説明します-実際にコードが何をしているかによって異なります。コードがこのパターンに従っている場合は、ダーティリードなどに頼る前に、おそらくこれがより良い修正方法です。

5
Peter Barton