本文へスキップ
BecomeCoder

SQL データ操作 (DML)コース · 第5章 安全に変更する · レッスン21

ACID ― 信頼性を支える4つの約束

ブラウザで完結

導入

トランザクションが「なぜ安心して使えるのか」の裏には、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減っていることを確認しましょう。次に COMMITROLLBACK に変えて実行すると、2つの UPDATEまとめてなかったことになる(原子性)ことを見てください。

演習

BEGIN で始め、商品1(キーボード)の在庫を 5 減らし、商品2(マウス)の在庫を 5 増やして COMMIT するトランザクションを書いてください。

ヒント1を見る

UPDATE products SET stock = stock - 5 WHERE id = 1;... + 5 ... id = 2;BEGINCOMMIT で挟みます。

ヒント2を見る

BEGIN; UPDATE products SET stock = stock - 5 WHERE id = 1; UPDATE products SET stock = stock + 5 WHERE id = 2; COMMIT;

実際に動かしてみよう

下のエディタにクエリを書いて「実行」を押すと、ブラウザ内のSQLiteで結果が表示されます。本文の例をそのまま試したり、書き換えたりしてみましょう。

SQL — ブラウザ内で実行(SQLite)

ブラウザ内でSQLを動かす環境(SQLite)を読み込みます(初回のみ一瞬)。
スクロールして表示された時点でも自動で読み込まれます。