3

この興味深い記事を読んだ後、いくつか質問があります。

次の表は、デッドロックの状況を示しています。

ここに画像の説明を入力

T1 はテーブル t_lock1 の c1=5 のすべての行で X ロックを保持し、T2 はテーブル t_lock2 の C1=1 のすべての行で X ロックを保持します。

これらの各トランザクションは、以前に他のトランザクションによってロックされた行を更新しようとしています。これにより、デッドロックが発生します。

質問1

  • トランザクションはロックを取得しますか? テーブルからの読み取りは共有ロックによって行われ、テーブルへの書き込みは排他ロックを使用して行われることを知っています (デフォルトのロック設定について話しています)。

したがって、この例から、トランザクションロックを保持しているように見えます....それは正しいですか?

質問2

...T1 は、テーブル t_lock1 の c1=5 のすべての行で X ロックを保持しています...

  • 私が言ったように、ロックは行ごとではありません(作成することはできますが、作成者は言及していません)-では、なぜ彼は次のように言うのですか:C1=5 のすべての行で
4

2 に答える 2

1

トランザクションはロックを取得しますか?

いいえ。実行するステートメント-aSELECTまたはanUPDATEはロックを取得します。トランザクション分離レベルの設定に応じて、(共有)ロック(読み取り用SELECT)が保持される期間は異なります-それだけです。共有ロックは通常、ごく短時間しか保持されませんが、更新ロックと排他ロックはトランザクションが終了するまで保持されます。トランザクションはロックを保持している可能性がありますが、ロックを取得するのはトランザクションではありません...

* ... T1は、テーブルt_lock1のc1 = 5ですべての行にXロックを保持します...*
ロックは行ごとではないと言ったので、私見です(作成は可能ですが、作成者は言及していません)。それで、なぜ彼は言うのですか:C1 = 5のすべての行で?

ロック行ごとに行われます-デフォルトでは。しかし、なぜあなたは1行しかないのだと思いますC1=5か?複数(場合によっては数千)存在する可能性があり、ステートメントは、ステートメントの影響を受けるすべての行をUPDATEロックします。UPDATE

于 2012-09-04T00:53:22.793 に答える
1

質問 1 の場合: SQL Server は、U ロックを使用してソース テーブルの行を読み取り、更新の対象となる行のみを X ロックに変換して更新します。多くの行を読み取ってから、書き込む行に絞り込むことの違いに注意してください。これら 2 つのセットは異なる方法でロックされます。

クエリに選択がないため、U および X ロックのみが取得されます。S ロックは、更新中のテーブルに対する update-query には使用されません。これは、ヒューリスティックなデッドロック回避スキームです。

質問 2: ロックはさまざまな粒度で行うことができますが、行数が少ない場合は、通常は行ごとです (これは強制的に行うことができます)。おそらく作成者は、C1=1 の行のみを読み取ってロックする必要があることを意味する C1 のインデックスを想定しています。他のすべての行は変更されません。

インデックスがない場合、SQL Server は実際にテーブルのすべての行を読み取り、その間にそれらを U ロックし、次に C1=1 を満たす行を X ロックします。著者は、C1=1 の行のみが x ロックされると述べています。

于 2012-09-03T20:36:11.807 に答える