Query Go
処理をまとめて確定・取消 - BEGIN / COMMIT / ROLLBACK の使い方・オプション・サンプル

処理をまとめて確定・取消 - BEGIN / COMMIT / ROLLBACK

トランザクションの開始・確定・取り消しを行う基本コマンド。ACID の I (独立性) を支える仕組み

概念図

BEGIN / COMMIT / ROLLBACK diagram

構文

sql
BEGIN; ... COMMIT; -- or ROLLBACK;

サンプル

振込処理を 1 トランザクションにまとめ、両方成功したときだけ確定する

sql
BEGIN;
UPDATE accounts SET balance = balance - 1000 WHERE id = 1;
UPDATE accounts SET balance = balance + 1000 WHERE id = 2;
COMMIT;

トランザクションとは

トランザクションは 一連の SQL 操作をひとまとめにして、全て成功したときだけ確定する仕組みです。途中で失敗したら ROLLBACK ですべて無かったことにできます。

たとえば銀行振込では「引き落とし」と「入金」の両方が成功しないとデータが壊れます。トランザクションはこの「全か無か」を保証します。

ACID 特性

  • Atomicity (原子性): 全部成功するか全部無かったことになる
  • Consistency (整合性): 制約を壊さない状態から壊さない状態へ遷移する
  • Isolation (独立性): 並行実行しても直列実行と同じ結果に見える
  • Durability (永続性): COMMIT 後はクラッシュしても消えない

autocommit の RDBMS 差

  • PostgreSQL: デフォルトで autocommit ON。BEGIN 明示で明示的トランザクションに入る
  • MySQL: デフォルトで autocommit ON (SET autocommit=0 で OFF)。START TRANSACTION も可
  • SQL Server: デフォルトで autocommit ON。BEGIN TRAN/BEGIN TRANSACTION で開始し、明示的 COMMIT/ROLLBACK が必要
  • Oracle: 常に暗黙的にトランザクション中。DML 発行時点で開始し、COMMIT/ROLLBACK で区切る
sql
-- MySQL: autocommit を切って明示制御
SET autocommit = 0;
START TRANSACTION;
UPDATE inventory SET stock = stock - 1 WHERE id = 10;
COMMIT;

-- SQL Server
BEGIN TRAN;
UPDATE inventory SET stock = stock - 1 WHERE id = 10;
COMMIT TRAN;

長時間トランザクションの危険

トランザクションを開いたまま長時間放置すると、以下の問題が起きます。

  • ロックの滞留: 他セッションが待たされ、最悪デッドロック
  • PostgreSQL の VACUUM 阻害: 古いバージョンのタプルが回収されず、肥大化 (bloat)
  • UNDO/REDO ログの肥大: ディスク逼迫・復旧時間増加

トランザクションは短く保ち、ユーザー入力を待つ間などに開いたままにしないことが鉄則です。

エラー時の自動ロールバック

RDBMS によってエラー時の挙動が違います。

  • PostgreSQL: 1 つでも文がエラーになるとトランザクション全体が「abort 状態」になり、ROLLBACK しないと次の文を受け付けない
  • MySQL (InnoDB) / SQL Server: エラーになった文だけ失敗し、他の文は残る場合がある。アプリ側で明示的に ROLLBACK が必要

アプリケーションでは必ず try/catch でエラーを捕捉し ROLLBACK を呼ぶ実装にしましょう。

関連トピック