経験的にトランザクションの性質を知っている気になっているけれど、
ではACID特性のそれぞれを言葉で説明してみて, と言われると難しい.
おそらくAtomicityだけをACID特性と言ってきた気がする. Wikipediaから.
トランザクション分離レベルもこの際まとめておく.
不可分性(Atomicity)
- トランザクションに含まれるタスクが複数ある場合、全てのタスクが完全に完了するか、または全く実行されないか、いずれかであることを保証すること。
- 口座Aから口座Bに対して1万円送金する. 口座Aから1万円を引くタスクと口座Bに1万円を足すタスクの片方だけが実行されるとおかしなことになる.
- 両方のタスクが成功して取引引きが完了するか、両方のタスクが失敗して取引が失敗するかいずれか
一貫性 (Consistency)
- トランザクションの開始から終了までの間、操作対象のデータが正常範囲内に収まることを保証すること.
- 口座Aから口座Bに送金するケースで、口座Aに1万円しかないのに2万円送金しようとして一時的に口座Aが-1万円になることは一貫性に反する.
- 一貫性に反するイベントが発生したときにトランザクションを終了する.
独立性 (Isolation)
- トランザクション内の複数の操作は外部からは隠蔽されることを表す. 外部からはトランザクションの入りと出だけを知ることができる.
- 口座Aから口座Bに送金するケースで、口座Aから口座Bに1万円を送金する際に、中間状態として口座Aから1万円を減らしただけの状態が発生するものとする.
- 外部からは中間状態は見ることができず、口座Aから1万円が減り口座Bに1万円が足された状態のみを知り得る.
永続性 (Durability)
- DBMSの管理上の話. トランザクションが完了した場合,障害を受けたとしても完了後の状態を保持できることを表す.
- 通常、トランザクション操作はトランザクションログとしてストレージに記録される. トランザクションログはトランザクションの履歴で巻き戻したりできる.
- システムに異常が発生した場合、トランザクションんログを使って異常発生前の状態まで復旧できる.
ACIDの現実
- ACID特性を厳密に実装しようとすると、より広範囲のデータにアクセスする必要が発生する.
- 広範囲のデータにロックを掛けたり更新したりなどでパフォーマンスが落ちる. 実際はある程度妥協して実装される.
- ACID特性を実現する処理自体が失敗する可能性もある. ファイルシステムやバックアップ方式の工夫により冗長化する.
- 全ての処理を一度に実行することが求められるが、それは現実的には難しい. ログ先行書き込みとシャドウページング.
- トランザクション分離レベルを設定することで、トランザクションの並列実行時の厳密性とパフォーマンスのトレードオフを制御できる
トランザクション分離レベル
- Dirty read. トランザクションAとトランザクションBが並列実行. AはBの途中の状態を見ることができる.
- Non-repeatable read (Fuzzy read). トランザクションAとトランザクションBが並列実行. Aが同じデータを2度読む. 1度目はBが書いていない. 2度目はBが書いている. Aから見て1度目と2度目のデータが異なるか消えているように見える.
- Phantom read. Non-repeatable readと似ているが、特にAの繰り返し読み込みの間にBがデータを挿入し、Aから見て突然新しいデータが出現したように見えること.
- 微妙な違いだが、過去から現在に渡って存在しているものの過去の状態が見えることと、過去存在していないが現在見えることは異なり、それぞれ名前がついている.
ACID特性の厳密な実装にはパフォーマンス劣化とのトレードオフがあるため、
概念的に、使う側がトレードオフをコントロールできるようになっている. それがトランザクション分離レベル.
あくまで概念のためDBMSによってその扱いが異なる.
分離レベル | Dirty read | Non-repeatable read | Phantom read |
---|---|---|---|
Read Uncomitted | 発生する | 発生する | 発生する |
Read Comitted | 発生しない | 発生する | 発生する |
Repeatable Comitted | 発生しない | 発生しない | 発生する |
Serializable | 発生しない | 発生しない | 発生しない |