導入
トランザクションが「なぜ安心して使えるのか」の裏には、DBMS が守っている4つの性質があります。頭文字をとって ACID(アシッド) と呼びます。銀行・在庫・予約など「絶対に食い違ってはいけない」システムは、この ACID の上に成り立っています。
説明
flowchart TB
A["A ― Atomicity(原子性)<br/>全部やるか、全部やめるか。中途半端なし"]
C["C ― Consistency(一貫性)<br/>ルール(制約)を破る状態にはしない"]
I["I ― Isolation(独立性)<br/>同時に動く処理どうしが混ざらない"]
D["D ― Durability(永続性)<br/>COMMIT したら停電でも消えない"]
- 原子性(Atomicity)… トランザクション内の操作は「全部成功」か「全部取り消し」のどちらか。前レッスンの
COMMIT/ROLLBACKがこれです。 - 一貫性(Consistency)… 制約(
CHECK・外部キー等)を破るような結果にはならない。途中で違反が起きればアボートして守ります。 - 独立性(Isolation)… 複数のトランザクションが同時に走っても、互いの途中経過は見えず、順番に実行したのと同じ結果になる。
- 永続性(Durability)…
COMMITした変更は、たとえ直後に電源が落ちても失われない(ディスクに記録される)。
在庫の付け替えを例にすると、ACID のありがたみが分かります。「商品4を1つ減らし、商品3を1つ増やす」――この2つは必ずセットであってほしい。トランザクションにまとめれば、片方だけ反映される事故が起きません(原子性)。
BEGIN;
UPDATE products SET stock = stock - 1 WHERE id = 4;
UPDATE products SET stock = stock + 1 WHERE id = 3;
COMMIT;
SELECT id, name, stock FROM products WHERE id IN (3, 4);
一貫性の例も見てみましょう。在庫は0未満にできない、というルール(CHECK (stock >= 0) 相当)があるとき、在庫を減らしすぎる更新は弾かれ、トランザクションは中途半端な結果を残しません。「ルールを破る状態には決してしない」――これが DB を“信頼できる記録”にしています。
やってみよう
初期表示のトランザクションを実行し、続く SELECT で商品3の在庫が1増え、商品4が1減っていることを確認しましょう。次に COMMIT を ROLLBACK に変えて実行すると、2つの UPDATE がまとめてなかったことになる(原子性)ことを見てください。
演習
BEGIN で始め、商品1(キーボード)の在庫を 5 減らし、商品2(マウス)の在庫を 5 増やして COMMIT するトランザクションを書いてください。
ヒント1を見る
UPDATE products SET stock = stock - 5 WHERE id = 1; と ... + 5 ... id = 2; を BEGIN〜COMMIT で挟みます。
ヒント2を見る
BEGIN; UPDATE products SET stock = stock - 5 WHERE id = 1; UPDATE products SET stock = stock + 5 WHERE id = 2; COMMIT;