RDBのトランザクション分離レベル
概要
DB の ACID 特性における Isolation に関するもの
英語では単に Isolation でいいらしい
DB の性能を上げるために複数のトランザクションを並行処理した結果として付随する問題
DB の一貫性と性能のトレードオフ
トランザクションの実行中にどんなデータの変化を見てしまわないかを保証すること
データの変化には「レコード単位のデータの再現保証」と「テーブル単位のデータの再現保証」の2種類がある (標準SQLで定義されているらしい)
アプリケーション側で一貫性を担保して DB の分離レベルを下げるというのは有り
DB の実装によってある分離レベルで発生する現象に差がある
便利な表
table:isolation
分離レベル \ 発生現象 Darty Read Non-repeatable Read Phantom Read 性能 一貫性
READ UNCOMMITTED 起きる 起きる 起きる 高い 低い
READ COMMITTED 起きない 起きる 起きる
REPEATABLE READ 起きない 起きない 起きる
SERIALIZABLE 起きない 起きない 起きない 低い 高い
table:isolation
分離レベル \ 保証 レコード単位のデータ再現保証 テーブル単位のデータ再現保証
READ COMMITTED 保証無し (Non-repeatable Read) 保証無し (Phantom Read)
REPEATABLE READ 保証有り 保証無し
SERIALIZABLE 保証有り 保証有り
現象
トランザクションAとトランザクションBがあるとする
Dirty Read
Bでコミットされていないデータ(不完全なデータ、計算途中のデータ)をAで読み取ってしまう
Non-Repeatable Read
Fuzzy Read とも呼ばれるが Phantom Read と字面が似ていて混乱するので Non-Repeatable Read で統一したい
あるトランザクション内で同一レコードの読み取りが他トランザクションの影響を受けてしまう
同じ問い合わせを二回連続して繰り返しても同じ結果になることを保証できない
Aがあるレコードを読む、Bがそのレコードを更新しコミット、その後にAで再びそのレコードを読むと結果が変わってしまう
Phantom Read
他のトランザクションが追加したり削除したデータが途中で見えてしまう
Phantom Read が発生しないからといって SERIALIZABLE ではないことに注意 (PostgreSQL)
DB 実装の実装の差
Oracle Database のサポートする分離レベル全てにおいて Dirty Read は発生しない
InnoDB では REPEATABLE READ でも Phantom Read は発生しない
PostgreSQL 9.1以降では REPEATABLE READ でも Phantom Read は発生しない
参考