行のロックが増加したため、および/またはロックの保持に費やした時間が増加したために、テーブルに複合主キーを定義すると、複数のスレッドが更新されているときにデッドロックが発生する可能性が高くなるのではないかと考えていました。一度?
助けてくれてありがとう。
行のロックが増加したため、および/またはロックの保持に費やした時間が増加したために、テーブルに複合主キーを定義すると、複数のスレッドが更新されているときにデッドロックが発生する可能性が高くなるのではないかと考えていました。一度?
助けてくれてありがとう。
複合 PK を使用していて、大量のデータを並行して挿入している場合、リソース ハッシュの衝突が発生する可能性があります。実際の例については、「疑わしいデッドロックとそれほど論理的でないロックの奇妙なケース」を参照してください。
リソース ハッシュ衝突の説明については、 「%%lockres%% 衝突確率マジック マーカー: 16,777,215」で Remus Rusanu を引用します(読むことをお勧めします)。
SQL Server のロック マネージャーは、何をロックするかを認識せず、'リソース' (基本的には文字列) をロックするだけです。「リソース」をロック マネージャーに提示し、目的のロックを要求するのは、ストレージ エンジンのアクセス メソッドなどの高レベル コンポーネントの仕事です。ヒープまたは B ツリーの行をロックすると、ストレージ エンジンはレコード識別子から「リソース」を合成します。これらのリソースの長さには制限があるため、ストレージ エンジンはキーの有効長を、ロック マネージャーに提示できる最大長まで減らす必要があります。つまり、レコードのキーは 6 バイトに減らされます。これは、キーを 6 バイトのハッシュ値にハッシュすることによって実現されます。
[...]
6 バイトでは、281,474,976,710,656 の異なる可能な値があります。かなりの数ですよね?実際にはそれほど大きくありません。[...] したがって、SQL %%lockres%% ハッシュは、同じハッシュを持つ 2 つのレコードを 50% の確率でテーブルから、任意のテーブルから、わずか 16,777,215 レコードから生成します。
SQL Server のロック マネージャーは (直接 PK ではなく) ロックハッシュ値を使用するため、単一列 PK を使用したロックと複合 PK を使用したロックに違いはないと結論付けます。
SQL Server 2008R2 でのロックハッシュ キーの競合を最小限に抑える改善と同時実行性への影響
他のデータベース ベンダーとは異なり、SQL Server の Lock Manager には論理的なコンポーネントがあります。SQL Server は、ロック ハッシュ値を使用して、行、ページ、またはテーブルの物理的な説明を使用する代わりに、SQL Server ロック マネージャーのロック構造のロックを表します。その後、ロックハッシュ値はメモリに保持されます。
単一の列キーと複合キーからロックハッシュ値のハッシュ衝突が発生する可能性はこれ以上ないと結論付けます。SQL 2008R2 とのリンクに示されているように、ロックハッシュは大幅に改善され、具体的には複合キーに対処しました。
2008R2 より前のロックハッシュは、単一キーと複合キーの両方に対して完全ではありませんでした。
PK を短くすることをお勧めします。
.NET KeyValuePair と Tuple は適切なハッシュを生成しません。
一般に、よく設計されたコードではそうではありません。その理由は、デッドロックの原因とそれらを回避/排除する手法は、一般に時間に依存しないためです。ほとんどのデッドロックは、スレッド内のさまざまな更新パスが原因で発生します。たとえば、コード A は Table1 を更新してから Table2 を更新しますが、コード ブロック B は Table2 を更新してから Table1 を更新します。これを回避するためのテクニックは、さまざまなコード ブロックが同じ順序で項目を試行および更新することを保証することに関連しています。つまり、スレッド 1 が A をロックしていて B を更新しようとしているのに対し、スレッド 2 が B をロックしていて A を更新しようとしているというシナリオは避けてください。
ただし、これらの競合するコーディング ブロック/ステートメントが存在する場合、複合キーによってデッドロックが発生する頻度が高くなる可能性があると思います。基本的に、トランザクションの完了に時間がかかるほど、別のスレッドが他のリソースをロックしてデッドロックを引き起こす時間が長くなります。
非常に小さい/特定のエッジケースを除いて、複合キーがデッドロックの発生に影響を与えるとは思いません (少なくとも私の経験では)。