2


0

デッドロックを防ぐ方法はありますか(そして、発生するのは1つが発生し、1つが被害を受ける)

私はロックとデッドロックに関する記事を読みましたが、それは着陸しませんでした。 同じテーブルのレコードを編集しようとする2つの異なるプロセスを実行しています。 最初のプロセスは新しいデータを読み取り、それを外部パーティに送信し、それに応じてステータスを更新します。他のプロセスは外部パーティから受信結果を受信し、それに応じてステータスを更新します。

現在、ますますデッドロックが発生しています(この場合、2つのうちの1つが被害者であり、中止されます)。 あなたはそれを予想し、ステートメントを再実行しようとすることができるので、これまでのところこれでいいのですが、それから常に同じデッドロックが発生します。 それが私の最初の質問です。なぜ同じデッドロックが常に発生するのですか?

次に、別のプロセスが既に読み取りと更新を行っているときに、レコードの排他ロックを取得しないようにdbmsに指示する方法があります(ストアドプロシージャを使用して単一のレコードを更新します)他のプロセスの準備はできていますか? または、それはデッドロックについて言うにはあまりにも単純すぎることですか?

3番目かもしれませんが、どのロックが問題を引き起こしていたかをLINQ to SQLに尋ねる方法があるので、プロセスのどの部分が問題を引き起こしているかについてもう少し洞察を得ます。

2 Answer


4


SQLプロファイラーは、SQL Serverのデッドロックの問題を解決しようとするのに使用した最高のツールです。

トレースを開始します。[イベントの選択]タブで:事前に選択されているすべてのイベントのチェックを外します。 [すべてのイベントを表示]をオンにします。 「ロック」を展開します。 「デッドロックグラフ」、「ロック:デッドロック」、および「デッドロックチェーンのロック」を確認します。

トレースを実行し、デッドロックイベントをキャプチャします。

SQLプロファイラーでデッドロックイベントを表示します。 デッドロック表示はかなり良いです。 追加の詳細を取得するには、未加工のXMLを調べる必要がある場合があります。

この最初のパスで見つけたものを使用して、何を変更すべきかを考えたり、SQLプロファイラーでトレースする他のイベントを提案したりできます。


1


@Darryl Petersonが示すように、SQLプロファイラーはデッドロック情報をキャプチャするための優れたツールです。 デッドロックがいつ発生するかわからない場合は、SQL Serverトレースフラグを設定してデータをキャプチャできます。

DBCC TRACEON (1204)

デッドロックが発生すると、デッドロックに関する情報がSQL Serverエラーログに書き込まれます。

デッドロックを取得する方法はいくつかあります。 最初の質問「なぜ同じデッドロックが常に発生するのか」は、おそらく良い兆候です。 デッドロックが繰り返し可能な場合は、キャッチして修正できます。

2番目の質問に関して、SQL Serverはおそらく、1つのプロセスが他のプロセスが完了するまで待機するように既に指示しています。 ただし、待機してデッドロックを回避することはできません。 デッドロックは、プロセスが別のプロセスによって保持されているリソースを使用しようとしている状況です。 しかし、他のプロセスは、最初のプロセスが保持しているリソースを待っています。 どちらのプロセスも、作業が完了するまでリソースを解放しません。 これは簡単な説明であり、より複雑なデッドロック状態が発生する可能性があることに注意してください。 ポイントは、デッドロック内のプロセスが完了できないことです。

デッドロックに関係するプロセスについて詳しく知ると、それを回避するための手順を実行できるようになります。