データベース ・ Chapter 9

トランザクション

記事 ・ 冒頭を無料公開中

実はファイル保存には、ある壁があります。例えば銀行アプリで、送金の処理が「Aの残高を減らす→Bの残高を増やす」の2つの処理を実行する場合、1手目の直後にプログラムが落ちたら、Aの残高が消えてしまいます。このような状態を避けるために、データベースには、中途半端を残さない仕組みがあリマス。コースの仕上げにふさわしい、データベースの一番誠実な機能である"トランザクション"を扱います。

シードファイル

「セットでなければならない」処理

商品が1個売れたとき、データベースで起きるべきことは2つあります。

UPDATE products SET stock = stock - 1 WHERE id = 1;   -- ①在庫を減らす
INSERT INTO orders (product_id, quantity) VALUES (1, 1);  -- ②注文を記録する

この2文は、両方成功するか、両方起きないかでなければいけません。①だけ成功して②が失敗したら、在庫は減ったのに注文記録がない。商品が1個、帳簿から消えます。②だけ成功したら、注文はあるのに在庫が減っていない。売り切れの商品をまた売ってしまいます。どちらの「片方だけの世界」も、事故です。

しかし現実には、処理は途中で止まり得ます。サーバーの電源断、プログラムのバグ、通信の切断、②の直前で止まる可能性は、ゼロにできません。「途中で止まらないよう祈る」は対策ではない。必要なのは、止まっても片方だけの世界が残らない仕組みです。

BEGINとCOMMIT

その仕組みがトランザクションです。使い方は、束ねたい文たちを BEGIN と COMMIT で挟むだけです。

BEGIN;
UPDATE products SET stock = stock - 1 WHERE id = 1;
INSERT INTO orders (product_id, quantity) VALUES (1, 1);
COMMIT;

BEGIN が「ここから束を始めます」、COMMIT が「束の全部を、正式に確定します」。BEGINからCOMMITまでの間の変更は、下書きの状態です。COMMITした瞬間に、束がまるごと本物になる。そして途中で何かが起きて COMMITにたどり着けなければ、下書きはまるごと破棄され、BEGINの前の世界に戻ります。

▶ 実行してみよう

イヤホンの在庫が2になり、注文が1件入っています。

ROLLBACK

途中で止まったときに戻るだけでなく、自分から「やっぱり無し」と宣言することもできます。COMMITの代わりに ROLLBACK と書きます。

▶ 実行してみよう

このチャプターの続きは受講生限定です

本文の残り、図解・実行できるコードブロック・演習はプラン加入後に読めます。

料金プランを見る