ACID特性
1. Atomicity(原子性)
→ すべての処理が「全部成功する」か「全部失敗して取り消す」かのどちらか。
(例: 銀行振込で「残高引き落とし成功 → 入金失敗」とかは起きない)
2. Consistency(一貫性)
→ トランザクション実行後もDBがルールを守った状態に保たれる。
(例: 負の残高を許さない制約を破らない)
3. Isolation(分離性)
→ 同時に走るトランザクションが互いに干渉しない。
(例: 他の人がまだ確定していないデータを読み込まない)
4. Durability(永続性)
→ コミット後のデータは障害が起きても失われない。
(例: 電源が落ちても振込処理が残っている)
トランザクション分離レベル(Isolation Levels)
SQL標準で定義されている「同時実行時の干渉をどこまで許すか」という設定。
1. READ UNCOMMITTED(非推奨)
未コミットの変更も読めてしまう(ダーティリードが発生)。
PostgreSQLはこのレベルを実装しておらず、READ COMMITTED と同じ扱いにする。
2. READ COMMITTED(コミット済のみ読む) ← PostgreSQLのデフォルト
1クエリごとに「その時点でコミットされたデータだけ見える」。
ダーティリードは起きない。
3. REPEATABLE READ(繰り返し読み取り)
トランザクション開始時点のスナップショットを固定して読む。
Phantom Read(同じ条件で再検索したのに新しい行が見える)が PostgreSQL では発生しない。
4. SERIALIZABLE(直列化)
すべてのトランザクションを「直列で実行したのと同じ結果」にする。
PostgreSQLは「Serializable Snapshot Isolation (SSI)」という高度な仕組みで実現。
代表的な異常系 (Anomalies)
↑で言及している、SQL標準で定義されている「起きてほしくない現象」
-
Dirty Read(ダーティリード)
→ 他のトランザクションがまだコミットしていない変更を読んでしまう。
(例: Aさんが残高100→50に変更中、Bさんがその50を読んで処理するが、Aさんがロールバックしたら消える値を使ってしまう) -
Non-Repeatable Read(非再現読)
→ 同じクエリを2回発行したのに結果が変わる。
(例: 1回目に残高50を見たのに、他のトランザクションが更新して2回目には70になっている) -
Phantom Read(ファントムリード)
→ 同じ条件で検索したのに、2回目の検索で新しい行が増えている。
(例: 「残高>100の口座」を検索 → 2回目には別の人がINSERTして結果が増えてる)
SQL標準の Isolation Levels
それぞれ「どの異常を防ぐか」で特徴がある。
レベル | Dirty Read | Non-Repeatable Read | Phantom Read | 説明 |
---|---|---|---|---|
READ UNCOMMITTED | ❌防げない | ❌防げない | ❌防げない | 未コミットデータまで見える最弱レベル |
READ COMMITTED | ✅防ぐ | ❌防げない | ❌防げない | 1クエリごとに「その時点でコミット済みのデータ」だけ見える |
REPEATABLE READ | ✅防ぐ | ✅防ぐ | ❌防げない | トランザクション開始時点のスナップショットを固定して読む |
SERIALIZABLE | ✅防ぐ | ✅防ぐ | ✅防ぐ | 直列に実行したのと同じ結果を保証 |