途中で止まったら、どうなるか
口座Aから口座Bへ 100,000 円を振り替える処理を考えます。データベースの中では、次の2つの書き換えが必要です。
- 口座Aの残高から 100,000 円を引く
- 口座Bの残高に 100,000 円を足す
もし1つ目が終わった直後に停電やエラーで止まったら、100,000 円がどこにもない状態になります。経理でいえば、借方だけ記帳して貸方を書き忘れた仕訳と同じで、帳簿が合わなくなります。
トランザクション:全部やるか、全部やらないか
そこでデータベースには、複数の書き換えを ひとまとまり として扱う仕組みがあります。これを トランザクション と呼びます。
BEGIN; -- ここからひとまとまり
UPDATE accounts SET balance = balance - 100000 WHERE id = 'A';
UPDATE accounts SET balance = balance + 100000 WHERE id = 'B';
COMMIT; -- 全部うまくいったので確定- COMMIT(コミット):まとまり全体を確定する
- ROLLBACK(ロールバック):まとまり全体を取り消し、始める前の状態に戻す
途中でエラーが起きたら ROLLBACK され、口座Aの引き落としもなかったことになります。「片方だけ終わった」という中途半端な状態は残りません。
大勢が同時に書き換えるとき
ネット通販で、在庫が残り1個の商品を2人が同時に注文したとします。2人とも「在庫1」を見て注文を確定すると、在庫がマイナスになってしまいます。
データベースは、書き換え中の行に ロック(鍵)をかけ、後から来た人をトランザクションが終わるまで待たせます。2人目は在庫が0になった後の状態を見るので、「在庫切れ」と正しく案内できます。
4つの約束(ACID)
トランザクションが守る性質は、頭文字をとって ACID(アシッド)と呼ばれます。名前だけ覚えておけば十分です。
- A 原子性:全部やるか、全部やらないか
- C 一貫性:決めたルール(残高はマイナスにしない、など)を破らない
- I 独立性:同時に動く処理どうしが、互いの途中の状態を見ない
- D 永続性:COMMIT した結果は、その後に停電しても消えない
この章のポイント
- 複数の書き換えは、トランザクションでひとまとまりにする
- うまくいったら COMMIT、途中で失敗したら ROLLBACK で元に戻る
- 同時の書き換えは、ロックで順番に整理される