7

PostgreSQL では、MVCC 同時実行制御メカニズムは次のように述べています。

データのクエリ (読み取り) のために取得された MVCC ロックは、データの書き込みのために取得されたロックと競合しないため、読み取りによって書き込みがブロックされることはなく、書き込みによって読み取りがブロックされることもありません。

したがって、READ_COMMITTED の場合でも、 UPDATE ステートメントは現在影響を受けている行をロックするため、現在のトランザクションがコミットまたはロールバックされるまで、他のトランザクションはそれらを変更できません。

並行トランザクションがロックされた行に対して UPDATE を発行すると、最初のトランザクションがロックを解放するまで、2 番目のトランザクションはブロックされます。

  1. この動作は、書き込みと書き込みの競合を防止しようとしていますか?

  2. 最初のトランザクションがコミットされた後、2 番目のトランザクションが行を上書きするため (UPDATE クエリの開始とクエリの終了の間にデータベースが変更された場合でも)、更新の損失は READ_COMMITTED でも発生する可能性があります。それでも更新が失われる可能性がある場合、2 番目のトランザクションを待たなければならないのはなぜでしょうか? 行レベルのスナップショットを使用してコミットされていないトランザクションの変更を保存し、トランザクションが書き込みロックが解放されるのを待たなければならないのを回避できませんでしたか?

4

1 に答える 1

4

最初の質問への答えはイエスです。ダーティ ライトをサポートできる DBMS はありません。T1 と T2 の 2 つのトランザクションが同時に実行されており、T2 が T1 からの更新を上書きする場合、T2 の更新が既に発生しているため、システムは T1 が後で ROLLBACK を発行するケースを処理できません。

ダーティ ライトを回避するために、スナップショット分離の元の定義は「最初のコミッターが勝つ」でした。つまり、競合する書き込みの発生は許可されますが、COMMIT を発行する最初のトランザクションのみが可能であり、他のすべての競合するトランザクションはコミットする必要があります。ロールバック。しかし、このプログラミング モデルは、トランザクションがデータベースの大部分を更新するだけで、最後にコミットする機能を拒否する可能性があるため、無駄ではないにしても、多少問題があります。そのため、MVCC をサポートするほとんどの DBMS システムは、「最初のコミッターが勝つ」のではなく、かなり伝統的な 2 フェーズ ロックを使用して「最初の更新者が勝つ」を実装しています。

于 2015-05-30T13:59:23.050 に答える