今回はトランザクションのACID特性と分離レベルについて調査しました。
ACID特性とは、トランザクションで処理するデータの整合性を保つ(データの信頼性を保証する)ために必要な4つの特性です。
Atomicity(原子性)、Consistency(一貫性)、Isolation(独立性)、Durability(耐久性)の頭文字を取ってACID特性と呼ばれています。
Atomicity(原子性)
トランザクションは、そのすべてを反映させるか、そのすべてを取り消すかの状態であること
Consistency(一貫性)
トランザクションは、その前後でデータの整合性が保たれ、矛盾のない状態が継続されること
Isolation(独立性)
トランザクションでは、同時並行処理結果(Parallel)も逐次処理結果(Serial)も同じであること
処理中の過程が外部から隠蔽されており、他の処理から影響を受けない/他の処理に影響を与えないこと
Durability(耐久性)
トランザクションは、処理が完了したら、その結果が障害などで影響を受けず、不変に保たれること
トランザクション(ANSI/ISO SQL規格)の分離レベルとは、複数のトランザクションの処理を同時に実行した際、各トランザクションの処理の一貫性をどこまで保証するかトランザクション同士の影響度を4段階で定義したものです。
一般的に複数の処理を実行する際、並列度が高いほど処理は速くなります。
ただし、データベースのように共通のデータを複数のトランザクションが処理する場合、並列度を高くして処理を速めたからと言って処理対象のデータが必ずしも一貫性がある(正しいデータの状態が保証されている)とは限りません。
・処理性能を上げる代わりにデータの一貫性を下げるか
・データの一貫性を上げる代わりに処理性能を下げるか
というようにトレードオフになっています。
このトレードオフの関係を4段階で定義したものが分離レベルです。
READ UNCOMMITTED (非コミット読取り)
確定していないデータまで読み取る
他のトランザクションの処理による更新途中のデータまで読み取る
データの一貫性は低いが処理性能は高い
READ COMMITTED (コミット読取り)
確定した最新データを常に読み取る
他のトランザクションの処理は常にコミット済みのデータのみ読み取る
REPEATABLE READ (リピータブル・リード)
読み取り対象のデータを常に読み取る
特定のトランザクションの処理が実行中の間、読み取り対象のデータは読み取り途中で他のトランザクションによって変更されない
同じトランザクション中では同じデータは毎回同じ値を読むことができる
SERIALIZABLE (シリアライズ可能)
直列化可能
並列で実行している複数のトランザクションの処理の結果が、逐次実行した場合と同じ結果となる
データの処理性能は低いが一貫性は高い
データの一貫性を下げる振る舞いとして、3種類のデータリード現象が定義されています。
ダーティリード (Dirty Read)
特定のトランザクションで変更したデータをCOMMITしていないにもかかわらず、別のトランザクションが読込めてしまう現象
ノンリピータブルリード (Non-repeatable Read) / ファジーリード (Fuzzy Read)
特定のトランザクション実行中に読み込んだデータが、別のトランザクションでデータ変更・COMMITしたことにより、1回目の読込みデータと2回目の読込みデータに差異が発生する現象
ファントムリード (Phantom Read)
特定のトランザクション実行中に読み込んだデータが、別のトランザクションでデータ挿入/削除・COMMITしたことにより、1回目の読込みデータと2回目の読込みデータに差異が発生する現象
分離レベルとリード現象の関係性をまとめました。
※Oracleの場合、READ COMMITTEDとSERIALIZABLEを提供しています
■分離レベルの設定
SET TRANSACTION句で設定できます