データベース ・ 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 と書きます。
▶ 実行してみよう
このチャプターの続きは受講生限定です
本文の残り、図解・実行できるコードブロック・演習はプラン加入後に読めます。