分離レベルは、読み取り中のデータの共有ロックが保持される期間に関するものです。しかし、Lieven がすでに述べているように、これらはデータベースの「破損」を防止するためのものではなく、リーダーとライターが互いの邪魔にならないようにするためのものです。
最初に: 書き込み操作 ( INSERT
、UPDATE
) には常にその行の排他ロックが必要であり、排他ロックは他のものと互換性がありません。したがって、更新する行が既にロックされている場合、UPDATE
操作は待機する必要があります。このあたり。
データを読み取るために、SQL Server は共有ロックを取得します。分離レベルは、それらが保持される期間に関するものです。
デフォルトの分離レベル ( READ COMMITTED
) は、SQL Server が行の共有ロックを取得しようとし、成功した場合は行の内容を読み取り、そのロックをすぐに解放することを意味します。したがって、ロックは、行が読み取られる短い期間だけ存在します。共有ロックは他の共有ロックと互換性があるため、任意の数のリーダーが同時に同じ行を読み取ることができます。ただし、共有ロックは排他ロックを防止するため、共有ロックはほとんどUPDATE
同じ行で防止します。
そして、READ UNCOMMITTED
基本的にロックを解除しない分離レベルもあります。つまり、現在更新されていて排他的にロックされている行を読み取ることもできるため、コミットされていないデータを取得する可能性があります-最終的にデータベースに実際に保存されることさえないデータ(更新するトランザクションがロールバックされる場合) -これには注意してください!
次のレベルは ですREPEATABLE READ
。この場合、一度取得された共有ロックは、現在のトランザクションが終了するまで保持されます。これにより、より多くの行がロックされ、長期間にわたってロックされます。読み取った行は「背後で」更新に対してロックされるため、読み取りは繰り返し可能です。
そして究極のレベルは、現在のトランザクションが終了するまでSERIALIZABLE
行の範囲全体 ( のWHERE
句で定義SELECT
) がロックされることです。
アップデート:
ダウンロード部分以上 (私にとっては 2 番目) 5 人のユーザーが同時に 1 つのデータベースを更新しようとしていることが心配です。
心配はいりません。SQL Server はこれを問題なく処理します。
これらの 5 (または 50) の同時ユーザーが異なる行を更新している場合、他のユーザーがいることにさえ気付かないでしょう。更新が行われ、その過程でデータが損なわれることはありません。すべて問題ありません。
これらのユーザーの一部が同じ行を更新しようとすると、シリアル化されます。最初のものは、行の排他ロックを取得し、更新を行い、ロックを解放してから続行できます。これで、2 番目のユーザーがチャンスを得ます。排他ロックを取得し、データを更新し、ロックを解除して続行します。
もちろん、何もしなければ、2 番目のユーザーのデータが最初の更新を上書きするだけです。そのため、並行性チェックが必要です。データを読み取ってから書き込むまでの間にデータが変更されたかどうかを確認する必要があります。変更されている場合は、他の誰かがその間に既に更新していることを意味します->この場合の同時実行競合解決戦略を考える必要があります(ただし、それ自体はまったく別の質問です....)