トランザクションの分離とは
##トランザクションとは
1つの作業単位として扱う一連の操作の集まりです。
トランザクション内の操作が全て実行されるか、または全て実行されないことを保証してくれます
分離性 (Isolation)
トランザクション中に行われる操作は他のトランザクションに影響を与えない性質です。つまり、それぞれのトランザクションは分離された状態で操作を行わなければなりません。
トランザクションのレベル
標準SQL
Pogresql (v12)
リードアンコミッティド
分離性
- 他のトランザクションのアンコミッティドのものもう収集されます
問題
- トランザクションA: レコードAをテーブルに追加
- トランザクションB: テーブルにSELECTする → レコードAが出ます
- トランザクションA: RollBackする
- トランザクションBの方はレコードA取れましたが、レコードAがDBに入らなかった → ダーティリード
リードコミッティド
分離性
- PostgreSQLではリードコミッティドがデフォルトの分離レベルです
- 他のトランザクションのまだコミットされていないデータは取得しません。
問題
- すでにテブールにレコードAがあります。
- トランザクションA: レコードAをレコードBに更新します。
- トランザクションB: テーブルにまたSELECTする → レコードAが出ます(レコードBが出ません)
- トランザクションA: COMMITする
- トランザクションB: テーブルにまたSELECTする → レコードBが出ます(レコードAが出ません)
- トランザクションBは2回同じクエリー実行しましたが、結果が違います。 → 反復不能読み取り
注意
- PostgreSQLの場合、リードアンコミッティドが存在しません。
- 理由はPostgreSQLはMulti-version concurrency controlを使っています。(詳しくはまだ分かりません)
リピータブルリード
分離性
- リードコミッティドと同じですが、トランザクション内で同じクエリー実行するといつも同じ結果になります。
問題
- すでにテブールにレコードAとレコードBがあります。
- トランザクションA: テーブルの全部のレコードをカウントします。 → 結果は2になります。
- トランザクションB: テーブルにレコードCを追加します。
- トランザクションB: Commitします。
- トランザクションA: テーブルの全部のレコードをカウントします。 → 結果は2になります。
- レコードCが追加されましたが、トランザクションAの結果は3じゃなく、2になります。 → ファントムリード
シリアライザブル
分離性
- 最も厳しいトランザクションの分離性
- トランザクションが同時にではなく、次から次へと、あたかも順に実行されます。
参考