3秒でわかる
変更を適用前の状態へ戻す操作。データベースの取り消し、デプロイの切り戻し、バージョン管理での打ち消しなど、被害を止める最初の手段になります。
もう少し詳しく
どういうものか
加えた変更を破棄し、変更前の状態へ引き戻す操作を指します。もっとも厳密な形はデータベースのトランザクションで、開始してから確定するまでの間に加えた変更をまとめて無かったことにできます。
同じ言葉は運用の場面でも使われます。本番へ出した新しいバージョンで障害が出たとき、直前の安定版へ戻すこともロールバックと呼びます。前者は仕組みとして保証された取り消し、後者は「前の状態を再現する」という運用手順で、確実さの性質が違う点は意識しておく必要があります。
なぜ必要か
処理が途中で失敗したときに、半分だけ進んだ状態が残るのが最大の問題だからです。口座 A から引き落として口座 B へ入金する処理が引き落とし直後に落ちれば、お金が消えます。全部成功したか、何も起きなかったか、の二択に押し込めるためにこの仕組みがあります。
障害対応でも、原因を突き止めて直すより先に戻すほうが速いという判断が成立します。停止時間を短くすることが優先で、調査は元の状態に戻してから落ち着いて行えます。
具体例
在庫を減らして注文を作る処理は、片方だけ成功すると帳尻が合いません。
START TRANSACTION;
UPDATE products
SET stock = stock - 1
WHERE id = 42 AND stock > 0;
-- 更新された行が 0 なら在庫切れなので中止する
INSERT INTO orders (product_id, user_id, quantity)
VALUES (42, 7, 1);
-- 途中で問題が起きた場合
ROLLBACK;
-- 問題が無ければ確定させる
-- <a href="/glossary/commit" class="text-primary font-medium underline underline-offset-2 hover:text-primary-dark">COMMIT</a>;# 公開済みのコミットを打ち消す。履歴は残る
git revert a1b2c3d
# 手元のブランチを 1 つ前へ戻す。共有済みなら使わない
git reset --hard HEAD~1つまずきやすいところ
自動コミットが有効なままロールバックを書いても効きません。多くのクライアントは既定で 1 文ごとに確定してしまうため、明示的にトランザクションを開始していない限り、戻す対象そのものが残っていません。
DDL の扱いも要注意です。MySQL では ALTER TABLE や DROP TABLE を実行した時点で暗黙のコミットが走り、取り消せません。PostgreSQL は DDL も取り消せるため、同じ感覚で移ると事故につながります。
デプロイの切り戻しでは、アプリを戻してもデータベースのスキーマは戻らない点が抜けがちです。列を削除する変更を入れた後に戻すと、古いアプリが存在しない列を参照して起動しません。削除は追加と分けて後日行う、という手順にしておくと戻せる余地が残ります。
似た用語との違い
コミットが変更を確定させる操作で、ロールバックはその反対にあたります。復元はバックアップから丸ごと書き戻す作業で、対象期間も所要時間も桁が違います。ロールバックで済むならそちらを選び、済まないときに復元へ進みます。