トランザクションとACID
トランザクションとは
トランザクションは、複数のデータベース操作をひとまとまりの処理として扱う仕組みです。「全部成功したら確定、途中で失敗したら全部なかったことにする」— この二択しかない、というのがポイントです。
定番の例が銀行の振込です。「Aさんの口座から1万円引く」「Bさんの口座に1万円足す」の2つの更新は、片方だけ成功すると口座残高が合わなくなります。トランザクションで包めば、途中で障害が起きても中途半端な状態が残りません。
ACID特性
トランザクションが満たすべき4つの性質の頭文字が ACID(アシッド)です。
| 特性 | 意味 |
|---|---|
| Atomicity(原子性) | 全部成功か全部失敗か。中間はない |
| Consistency(一貫性) | 実行前後でデータの整合性ルールが守られる |
| Isolation(独立性) | 同時に動く他のトランザクションから干渉されない |
| Durability(永続性) | 確定(コミット)した結果は障害でも失われない |
[[リレーショナルデータベース]] はこの ACID を保証することを大きな特徴としています。電源が落ちても永続性(D)が守られるのは、変更を先にログへ書いてから反映する [[トランザクションログとWAL]] の仕組みがあるからです。
使い方 — BEGIN / COMMIT / ROLLBACK
[[SQL]] では次の3つの命令でトランザクションを制御します。
BEGIN; -- トランザクション開始
UPDATE accounts SET balance = balance - 10000 WHERE name = 'A';
UPDATE accounts SET balance = balance + 10000 WHERE name = 'B';
COMMIT; -- 確定(失敗時は ROLLBACK)
- COMMIT(コミット)— ここまでの変更をまとめて確定する
- ROLLBACK(ロールバック)— ここまでの変更を取り消して開始前の状態に戻す
アプリケーションのコードでは「try で更新 → 成功なら COMMIT、例外が出たら ROLLBACK」という形が定番です。
初学者向けポイント
- 独立性(I)を厳密にするほど同時実行性能は下がる — 各データベースには分離レベルという調整段階があり、トレードオフを選べる
- 同時更新の制御には内部でロックが使われる — 詳細は [[ロックとデッドロック]] を参照
- トランザクションを長く開きっぱなしにしない(ロックが他の処理を待たせる)。必要な範囲だけ短く包むのが基本
- 複数サーバーにまたがる分散環境では ACID の完全な保証が難しくなる — 1つの分散データベース内部での整合性の考え方は [[CAP定理と分散データベース]]、複数サービスにまたがる更新をアプリ側でどうつなぐかは [[分散トランザクションとSaga]] が扱う
関連技術とのつながり
- [[リレーショナルデータベース]] — ACID 保証は RDB の看板機能
- [[SQL]] — BEGIN / COMMIT / ROLLBACK で制御する
- [[ロックとデッドロック]] — 独立性を実現する裏側の仕組み
- [[CAP定理と分散データベース]] — 分散環境での整合性の考え方
Q: トランザクションの基本的な性質はどれ?
- [x] 全部成功か全部なかったことにするかの二択になる
- [ ] 成功した操作だけが部分的に反映される
- [ ] 読み取り専用の操作しか含められない
解説: 途中で失敗したら全体を取り消す(原子性)ことで、振込の片側だけ反映されるような中途半端な状態を防ぎます。
Q: ACID の A(Atomicity)が意味するものはどれ?
- [ ] 確定した結果が障害でも失われないこと
- [ ] 他のトランザクションから干渉されないこと
- [x] 全部成功か全部失敗かで中間がないこと
解説: A は原子性です。永続性は D(Durability)、独立性は I(Isolation)が対応します。
Q: 途中まで行った変更を取り消して開始前の状態に戻す命令はどれ?
- [ ] COMMIT
- [x] ROLLBACK
- [ ] BEGIN
解説: ROLLBACK は変更の取り消し、COMMIT は確定、BEGIN はトランザクションの開始です。