11

デッドロックについての私の理解は、2 つのプロセスが同じリソースをめぐって競合しようとしているということです。通常、2 つのプロセスが同じデータ行に「書き込み」を試みています。1 つのプロセスがすべてデータの読み取りを行っており、もう 1 つのプロセスがデータの更新を行っている場合、リソースの競合はどのようになりますか? しかし、デフォルトのトランザクション レベル「ReadCommitted」に設定されているデータベースでは、いくつかのデッドロック例外が発生しています。ReadCommitted 定義 - 変更された (まだコミットされていない) データは読み取ることができません。それは問題ありませんが、この「ダーティ リード」が発生した場合、SQL Server はデッドロック例外をスローする必要がありますか? このシナリオで実際に経験した人はいますか? これが真実である可能性があると主張するブログ投稿 (stackoverflow 開発者によるものです:) を見つけました。

4

2 に答える 2

8

ReadCommittedトランザクション分離レベルは、最初Shared Lockにリソースの を取得します。つまり、行の読み取り中に取得しますが、行を更新しようとするとExclusive lock、リソースの を取得します。複数のユーザーが同じ行にロックを共有できますが、効果はありませんが、1 人のユーザーが行を更新しようとするとすぐに行に排他ロックがかかりdead lock、共有のために最初にレコードを表示できたユーザーが A になる可能性があります行をロックしますが、ユーザーが更新しようとすると、最初のユーザーによってすでに排他ロックが設定されています。User1 と User2 の両方がロックを共有していて、いくつかのレコードを更新しようとすると、他のユーザーがトランザクションをコミットする必要がある行に対して両方が排他ロックを取得するシナリオを想像してください。これによりデッドロックが発生します。
デッドロックの場合、Priority Level is not setSQL Server がしばらく待機してからRollBack、トランザクションがcheaperロールバックされます。
編集
はい、User1 がデータの読み取りのみを行っており、User2 が一部のデータを更新しようとしていて、そのテーブルに非クラスター化インデックスがある場合、可能です。

  1. User1 は一部のデータを読み取り、ルックアップを実行するために非クラスター化インデックスで共有ロックを取得し、データ自体を返すためにデータを含むページで共有ロックを取得しようとします。

  2. 書き込み/更新を行っている User2 は、最初にデータを含むデータベース ページで排他ロックを取得し、次にインデックスを更新するためにインデックスで排他ロックを取得しようとします。

于 2013-10-25T17:19:03.267 に答える
5

はい、起こりえます。それぞれ独自のトランザクションを持つ 2 つのプロセスがあるとします。最初に TableA を更新し、次に TableB を更新しようとします。2 番目は TableB を更新し、次に TableA を更新しようとします。運が悪いと、両方のプロセスが最初のステップを完了し、2 番目のステップを完了するためにもう一方のプロセスを無期限に待機します。

ちなみに、これはデッドロックを回避する最も一般的な方法の 1 つです。つまり、テーブルを更新する順序に一貫性を持たせることです。両方のプロセスが最初に TableA を更新し、次に TableB を更新した場合、デッドロックは発生しません。

于 2013-10-25T16:43:02.013 に答える