トランザクションとは
トランザクションとは、まとめて実行したい複数のSQL文を、1つのかたまりとして扱う仕組みのことです。トランザクション(transaction)は英語で「取引」「処理」という意味です。
たとえば、AさんからBさんへ1,000円を送金する場合を考えてみます。
- Aさんの口座残高から1,000円を引く
- Bさんの口座残高に1,000円を足す
この2つは、必ず両方とも成功する必要があります。
もし1だけ実行されて2が失敗すると、Aさんの口座から1,000円が消えただけになってしまうからです。
データの不整合を防ぐために用意されているのが、トランザクションです。
複数のSQL文をひとまとめにし、すべてが成功したときだけ反映するように扱います。
トランザクションを書くSQL
PostgreSQLの構文では BEGIN でトランザクションを開始し、すべての操作が終わったら COMMIT でデータベースに反映します。途中で何か問題が起きた場合は、ROLLBACK でトランザクション開始時点まで巻き戻します。
先ほどの送金例を書くと、次のようになります。
BEGIN;
UPDATE accounts SET balance = balance - 1000 WHERE name = 'A';
UPDATE accounts SET balance = balance + 1000 WHERE name = 'B';
COMMIT;
-
BEGIN;でトランザクションを開始 - Aさんの口座残高から1,000円を引く
- Bさんの口座残高に1,000円を足す
-
COMMIT;でデータベースに反映
ACID特性の全体像
トランザクションには、ACID特性と呼ばれる4つの性質があります。
| 特性 | 名称 | 内容 |
|---|---|---|
| A | 原子性(Atomicity) | すべて実行されるか、すべて実行されないか |
| C | 一貫性(Consistency) | 一貫した状態から一貫した状態へ |
| I | 独立性(Isolation) | 他のトランザクションの影響を受けない |
| D | 永続性(Durability) | コミット後の結果は失われない |
原子性(Atomicity)
原子性とは、トランザクション内のすべての操作が実行されるか、まったく実行されないかのどちらかであることを保証する特性です。
送金処理の途中でシステム障害が発生し、トランザクションが完了できなくなったとします。
このとき、原子性が保証されていれば、Aさんの口座からの引き落としも自動的にロールバックされ、最終的に元の状態に戻ります。部分的に成功した中途半端な状態が残ることはありません。
一貫性(Consistency)
一貫性とは、トランザクションの前後で、データベース内のデータが整合性制約に常に従っているという特性です。整合性制約とは、データに対して設定されたルールのことです。
送金の例で考えてみます。「口座の残高はマイナスになってはいけない」という整合性制約があり、Aさんの残高が500円のときに1,000円を送金しようとしたとします。
このとき、一貫性が保証されていれば、トランザクションはロールバックされ、整合性制約違反の状態が残ることはありません。
✍️ 補足
整合性制約には、たとえば「値がNULLであってはならない」「同じ値が重複してはならない」「特定の条件を満たす必要がある」などがあります。
独立性(Isolation)
独立性とは、複数のトランザクションが並行して実行されても、互いに邪魔されないことを保証する特性です。
在庫管理を例に考えてみます。ある商品の在庫が1個だけ残っているとして、ユーザーAとBが、ほぼ同時にこの商品を購入しようとしました。
もし独立性が保証されていないと、両方の処理が「在庫が1個ある」と読み取った状態でそれぞれ購入を進めてしまい、本来1人しか買えないはずの商品が2人とも買えてしまいます。
独立性が保証されていれば、片方の購入処理が完了するまでもう一方は待たされ、2人目は「在庫がない」と判定されて正しく購入できなくなります。
永続性(Durability)
永続性とは、コミットされたトランザクションの結果が永続的に保持されることを保証する特性です。システム障害が発生しても、コミット済みの変更が失われることはありません。
送金処理がコミットされた直後にデータベースサーバーが落ちたとします。
このとき、永続性が保証されていれば、サーバーが復旧したあともAさんとBさんの残高は送金後の正しい状態のまま保たれます。
コミット済みの変更が、障害によって失われることはありません。
これを実現するため、DBMSはトランザクションログという仕組みを使います。
コミット時に変更内容をログファイルに書き出してから完了を返すことで、メモリ上のデータが失われても、ログから復旧できる仕組みになっています。
まとめ
- 原子性:トランザクション内のすべての操作が「全部実行される」か「まったく実行されない」かのどちらか
- 一貫性:データが整合性制約に常に従っている状態を保つ
- 独立性:複数のトランザクションが並行して実行されても、互いに邪魔されない
- 永続性:コミットされたトランザクションの結果は永続的に保持される
参考




