brb tea が言うように、データベースの実装と使用するアルゴリズム (MVCC または Two Phase Locking) に依存します。
CUBRID (オープン ソース RDBMS)は、この 2 つのアルゴリズムの考え方を説明しています。
1 つ目は、T2 トランザクションが A レコードを変更しようとしたときです。T1 トランザクションが既に A レコードを変更していることを認識しており、T2 トランザクションは T1 トランザクションがコミットされるかロールされるかを認識できないため、T1 トランザクションが完了するまで待機します。戻る。この方法は 2 フェーズ ロック (2PL) と呼ばれます。
もう 1 つは、T1 トランザクションと T2 トランザクションのそれぞれが、独自の変更されたバージョンを持つことを許可することです。T1 トランザクションが A レコードを 1 から 2 に変更した場合でも、T1 トランザクションは元の値 1 をそのままにして、A レコードの T1 トランザクション バージョンが 2 であることを書き込みます。その後、次の T2 トランザクションが A レコードを変更します。 2 から 4 ではなく 1 から 3 であり、A レコードの T2 トランザクション バージョンは 3 であると記述しています。
T1 トランザクションがロールバックされる場合、T1 トランザクション バージョンである 2 が A レコードに適用されなくてもかまいません。その後、T2 トランザクションがコミットされると、T2 トランザクション バージョンである 3 が A レコードに適用されます。T1 トランザクションが T2 トランザクションの前にコミットされた場合、A レコードは 2 に変更され、T2 トランザクションのコミット時に 3 に変更されます。最終的なデータベース ステータスは、各トランザクションを個別に実行した場合のステータスと同じであり、他のトランザクションに影響を与えることはありません。したがって、ACID プロパティを満たします。この方法は、マルチバージョン同時実行制御 (MVCC) と呼ばれます。
MVCC では、メモリのオーバーヘッド (同じデータの異なるバージョンを維持する必要があるため) と計算 (REPETEABLE_READ レベルでは更新を失うことができないため、Hiberate のようにデータのバージョンをチェックする必要があるため) の増加という犠牲を払って同時変更が可能です。Optimistick Lockingで行います)。
2PLトランザクション分離レベルでは、以下を制御します。
トランザクション分離レベルを選択しても、データの変更を保護するために取得されるロックには影響しません。トランザクションは、そのトランザクションに設定された分離レベルに関係なく、変更するすべてのデータに対して常に排他的ロックを取得し、トランザクションが完了するまでそのロックを保持します。読み取り操作の場合、トランザクション分離レベルは主に、他のトランザクションによる変更の影響からの保護レベルを定義します。
分離レベルを低くすると、多数のユーザーが同時にデータにアクセスできるようになりますが、ダーティ リードや更新の消失など、ユーザーが遭遇する可能性のある同時実行効果の数が増加します。
SQL Serverにおけるロックと分離レベルの関係の具体例(READ_COMMITTED_SNAPSHOT=ON の READ_COMMITED 以外では 2PL を使用)
READ_UNCOMMITED: 現在のトランザクションによって読み取られたデータが他のトランザクションによって変更されるのを防ぐために、共有ロックを発行しないでください。READ UNCOMMITTED トランザクションは、他のトランザクションによって変更されたがコミットされていない行を現在のトランザクションが読み取れないようにする排他ロックによってもブロックされません。[...]
READ_COMMITED:
- READ_COMMITTED_SNAPSHOT が OFF に設定されている場合 (デフォルト): 共有ロックを使用して、現在のトランザクションが読み取り操作を実行している間、他のトランザクションが行を変更できないようにします。共有ロックは、他のトランザクションが完了するまで、ステートメントが他のトランザクションによって変更された行を読み取ることもブロックします。[...] 行ロックは、次の行が処理される前に解放されます。[...]
- READ_COMMITTED_SNAPSHOT が ON に設定されている場合、データベース エンジンは行のバージョン管理を使用して、ステートメントの開始時に存在していたデータのトランザクション的に一貫性のあるスナップショットを各ステートメントに提示します。ロックは、他のトランザクションによる更新からデータを保護するために使用されません。
REPETEABLE_READ: 共有ロックは、トランザクション内の各ステートメントによって読み取られるすべてのデータに配置され、トランザクションが完了するまで保持されます。
SERIALIZABLE: 範囲ロックは、トランザクションで実行される各ステートメントの検索条件に一致するキー値の範囲に配置されます。[...] 範囲ロックは、トランザクションが完了するまで保持されます。