コンテンツへスキップ
ホーム » 記事一覧 » トランザクションとは?COMMIT・ROLLBACKを具体例で解説

トランザクションとは?COMMIT・ROLLBACKを具体例で解説

「SQLを実行したあと、COMMITが必要と言われた」「ROLLBACKすれば元に戻ると聞いたけれど、どこまで戻るの?」。そんな疑問を理解する鍵が、トランザクションです。送金の例と短いSQLを使って、処理をまとめる理由から順に見ていきましょう。

💡 このページでわかること

  • トランザクションが必要になる理由
  • COMMITとROLLBACKの違い・取り消せる範囲
  • SQLで開始・変更・確定または取り消しを行う流れ

トランザクションとは?処理をひとまとまりにする単位

トランザクションとは、データベースへの処理を「まとめて確定するか、取り消すか」で扱うひとまとまりの単位です。データベースは、残高や注文などの情報を整理して保存する仕組みです。

たとえば送金では、「送る人の残高を減らす」と「受け取る人の残高を増やす」の両方がそろって、初めて正しい結果になります。片方だけが確定すると困る処理を、1つのトランザクションにまとめます。

変更を確定する命令がCOMMIT(コミット)、まだ確定していない変更を取り消す命令がROLLBACK(ロールバック)です。

具体例:1,000円の送金をひとまとまりにする

Aさんの残高が5,000円、Bさんの残高が2,000円だとします。AさんからBさんへ1,000円を送るには、次の2つの更新が必要です。

  1. Aさんの残高を1,000円減らし、4,000円にする。
  2. Bさんの残高を1,000円増やし、3,000円にする。

もし1の更新だけを確定したあと、2の処理に失敗したら、Aさんのお金だけが減ってしまいます。

そこで、2つの更新を1つのトランザクションにまとめます。両方が正しく完了したらCOMMITし、途中で続けられなくなったらROLLBACKします。取り消した場合は、Aさんが5,000円、Bさんが2,000円のままです。

Aさんの残高を5,000円から4,000円に、Bさんを2,000円から3,000円にする2つの更新を、1つのトランザクションにまとめる

大切なのは、「片方だけを確定した状態で終わらせない」ことです。ただし、送金先や金額の正しさまで自動で判断してくれるわけではありません。それらを確認し、確定するか取り消すかを決める処理も必要です。

COMMITとROLLBACKの違い

COMMITは「今回の変更で確定する」、ROLLBACKは「今回の未確定の変更を取り消す」という違いです。

命令役割送金の例での結果
COMMITトランザクションの変更を確定するAさん4,000円・Bさん3,000円
ROLLBACKトランザクションの未確定の変更を取り消すAさん5,000円・Bさん2,000円

どちらも、ここで扱う基本の使い方では現在のトランザクションを終了します。同じ変更について、COMMITとROLLBACKを両方順番に実行するものではありません。

BEGINで開始してデータを変更し、COMMITで確定するか、ROLLBACKで未確定の変更を取り消して終了する

ROLLBACKは、最後のSQLだけを取り消す命令ではありません。通常のROLLBACKでは、そのトランザクションで行った未確定の変更をまとめて取り消します。確定済みの過去の変更まで戻すことはできません。

SQLで確認:変更を取り消す場合・確定する場合

SQLは、データベースに検索や更新を指示するための言語です。ここではデータベース製品の1つであるPostgreSQLを使う例に絞ります。ほかの製品や接続ツールでは、開始方法や自動確定の設定が異なることがあります。

送金の仕組みを確認するための学習用SQLです。実際の送金システムには、残高不足や同時操作などに対応する追加の仕組みが必要です。

準備:練習用のデータを作る

練習用のPostgreSQLに接続し、SQL入力画面で次を実行します。接続ツールがSQLごとに自動確定する通常の設定で、ほかのトランザクションを開始していない状態を前提にします。この先の例も、同じ接続で順番に実行してください。

CREATE TEMP TABLE transaction_demo (
    name TEXT PRIMARY KEY,
    balance INTEGER NOT NULL
);

INSERT INTO transaction_demo (name, balance)
VALUES ('A', 5000), ('B', 2000);

transaction_demoは、データを行と列で保存する表(テーブル)の名前です。nameに名前、balanceに残高を入れています。CREATE TEMP TABLEは、その接続中だけ使う一時的な表を作る命令です。作成後、INSERTでAさんとBさんのデータを追加しています。

表の定義にあるTEXTは文字列、INTEGERは整数を表します。PRIMARY KEYは名前を重複させないための指定、NOT NULLは残高を未入力にしないための指定です。

取り消す例:ROLLBACKで元の残高に戻す

まず、次の範囲だけを実行します。BEGINがトランザクションの開始、UPDATEが更新、SELECTが内容の確認です。WHEREは更新する行を絞る条件です。

BEGIN;

UPDATE transaction_demo
SET balance = balance - 1000
WHERE name = 'A';

UPDATE transaction_demo
SET balance = balance + 1000
WHERE name = 'B';

SELECT name, balance
FROM transaction_demo ORDER BY name;

同じ接続で見ると、Aさんは4,000円、Bさんは3,000円になっています。ただし、まだ確定前です。今回は取り消すと決め、続けて次を実行します。

ROLLBACK;

SELECT name, balance
FROM transaction_demo ORDER BY name;

Aさんが5,000円、Bさんが2,000円に戻れば、取り消しを確認できています。この例ではエラーを起こさず、自分で取り消しています。ROLLBACKは、エラーが起きたときだけに使う命令ではありません。

確定する例:COMMITで変更を残す

先ほどのROLLBACK後に、次を実行します。新しいトランザクションで同じ更新を行い、今度はCOMMITします。

BEGIN;

UPDATE transaction_demo
SET balance = balance - 1000
WHERE name = 'A';

UPDATE transaction_demo
SET balance = balance + 1000
WHERE name = 'B';

COMMIT;

SELECT name, balance
FROM transaction_demo ORDER BY name;

結果はAさんが4,000円、Bさんが3,000円です。今度は確定済みなので、あとからROLLBACKしても、この送金前の残高には戻せません。なお、練習用の一時テーブル自体は、COMMITの有無にかかわらず接続終了時に削除されます。

どんな場面でトランザクションを使う?

一緒に成功させたいデータの変更がある場面で使います。

  • ネットショップ:注文を登録し、在庫数を減らす。
  • ポイント利用:ポイント残高を減らし、利用履歴を記録する。
  • 予約管理:予約を登録し、空き枠を減らす。

たとえば同じデータベースで注文と在庫を管理しているなら、両方の更新をまとめることで「注文だけが登録され、在庫が減らない」といった中途半端な結果を防ぎます。

ただし、メール送信や外部の決済サービスで行った処理まで、データベースのROLLBACKで取り消せるわけではありません。

初心者が注意したい3つのポイント

COMMIT後の変更はROLLBACKで戻せない

ROLLBACKで取り消せるのは、現在のトランザクションの未確定の変更です。「昨日の状態に戻す」「確定した更新をなかったことにする」という操作ではありません。

確定後の修正には、正しい値に更新し直すなど、状況に応じた対応が必要です。まず、どのデータをどう変更したかを確認しましょう。

自動コミットの設定を確認する

自動コミットとは、SQLの実行が成功するたびに、自動で変更を確定する動作です。PostgreSQLでは、明示的にBEGINでまとめていないSQLは、通常1文ずつトランザクションとして実行・確定されます。接続ツールが開始や確定を管理する場合もあります。

「あとでROLLBACKするつもりだったのに、すでに確定していた」を防ぐため、使用するツールの設定と、トランザクションの開始・終了の方法を確認してください。

エラーが出たら何でも自動で元通り、とは限らない

エラー時にどこまで取り消されるかは、製品やエラーの種類によって異なります。問題が起きたら、そのままCOMMITせず、状態を確認して取り消す処理が必要です。

また、対象の行がなく更新件数が0件でも、SQLエラーにならないことがあります。「エラーがなかった」だけでなく、想定した件数・内容になったかも確かめます。

表を作る・構造を変える命令にも注意が必要です。たとえばMySQLでは、ALTER TABLEなどを実行すると暗黙にCOMMITされる場合があります。「どのSQLでもROLLBACKできる」と考えず、利用する製品の仕様を確認しましょう。

よくある疑問

トランザクションは複数のSQLがあるときだけ?

いいえ。1つのSQLもトランザクションとして扱われます。複数の処理をまとめる例で考えると、「一緒に確定する単位」という役割がつかみやすくなります。

開始したままにしておいてもいい?

変更内容を確認したら、速やかにCOMMITかROLLBACKで終えましょう。長く開いたままにすると、ほかの更新が待たされるなどの原因になります。

関連用語の「ACID」とは?

ACID(アシッド)は、トランザクションの性質をまとめた呼び方です。原子性は「全部実行するか、全部取り消すか」、一貫性は「決められたデータのルールを保つ」、独立性は「同時に行う処理の影響を制御する」、永続性は「確定した結果を保持する」という意味です。

最初は4つの名前を暗記するより、「途中までの変更だけが確定すると困るから、ひとまとまりにする」と理解できれば十分です。なお、データのルールや同時操作の扱いは、システム側で適切に設計・設定する必要があります。

まとめ・関連記事

トランザクションは、処理をまとめて確定・取り消しするための単位です。COMMITで変更を確定し、ROLLBACKで未確定の変更を取り消します。

送金なら、「残高を減らす」と「残高を増やす」をひとまとまりにします。実際にSQLを使うときは、どこからどこまでが1つのトランザクションか、すでに確定していないかを意識しましょう。

データベースやSQLの基本を振り返りたい方は、次の記事も参考にしてください。

仕様を詳しく確認したい方へ:開始・確定・取り消しはPostgreSQL公式のトランザクション解説、表の操作による自動確定はMySQL公式の暗黙のCOMMITを参照してください(英語)。

コメントを残す

メールアドレスが公開されることはありません。 ※ が付いている欄は必須項目です