SQLでROLLBACKを使ってトランザクションを取り消す方法

ROLLBACKで取り消せるのは、原則として同じ接続でまだCOMMITしていないトランザクションの変更です。COMMIT後にROLLBACKを実行しても元へ戻りません。自動コミットが有効なまま実行した更新や、製品固有の暗黙コミットにも注意してください。以下の実行例はPostgreSQLの検証用データを使い、本番データや残高は操作しません。

データベースを操作する際、意図しない変更を加えてしまった場合、それを取り消す方法が必要です。SQLのROLLBACK文は、このような誤った変更を元に戻すための重要な機能です。本記事では、ROLLBACKを使ってトランザクションを取り消す方法について詳しく解説します。

目次

トランザクションとは

トランザクションは、データベース操作を一つの論理的な単位として扱う仕組みです。複数の操作を一つにまとめ、すべての操作が成功した場合にのみデータベースに反映されます。逆に、途中でエラーが発生した場合はすべての操作を取り消すことができます。これにより、データの整合性と一貫性を保つことができます。

トランザクションの開始

PostgreSQLではBEGINまたはSTART TRANSACTION、MySQLではSTART TRANSACTION、SQL ServerではBEGIN TRANSACTIONなど、製品に応じた構文を使います。すべてのDBで同じ開始文が使えるわけではありません。これにより、データベースは一連の操作を記録し、最終的な確定または取り消しの準備を行います。

BEGIN TRANSACTION;

-- ここに一連のデータベース操作を記述します

これにより、トランザクション内で行われるすべての操作は一つの単位として管理され、途中でエラーが発生した場合はROLLBACKによって一括で取り消すことができます。

コミットとロールバックはどちらか一方

成功を確認して変更を残すならCOMMIT、取り消すならROLLBACKです。両方を順番に並べても「エラーなら取り消す」という条件分岐にはなりません。SQLクライアントがエラー後に次の文を続行する場合もあるため、実行結果を確認し、エラー時は確定せず停止します。

-- 同じ接続で開始・更新・確認する
BEGIN;
-- 検証するDMLをここで実行
-- この例は確定せず取り消す
ROLLBACK;

未コミットでも同じトランザクションからは変更が見えます。他の接続からどう見えるかは分離レベルと製品に依存します。「COMMITまでは何も反映されない」という理解ではなく、「まだ確定していない」と区別してください。

ROLLBACKの使用例:検証用の一時テーブル

PostgreSQLで同じセッションのまま実行する例です。最初の準備は自動コミット状態で実行し、既存のトランザクション内では始めないでください。実際に利用中のテーブル名へ置き換える必要はありません。

CREATE TEMP TABLE rollback_demo (id integer PRIMARY KEY, label text);
INSERT INTO rollback_demo VALUES (1, 'before');

BEGIN;
UPDATE rollback_demo SET label = 'after' WHERE id = 1;
SELECT * FROM rollback_demo; -- この接続では after が見える
ROLLBACK;
SELECT * FROM rollback_demo; -- before に戻る

この例は明示的にROLLBACKを選んでいます。実アプリではDBドライバーのトランザクションAPIと例外処理を使い、失敗時にrollback、全処理と対象件数が正しいと確認した場合だけcommitします。途中で別の接続を開くと同じトランザクションにはなりません。

一部だけ戻す場合はSAVEPOINT

BEGIN;
UPDATE rollback_demo SET label = 'step1' WHERE id = 1;
SAVEPOINT before_step2;
UPDATE rollback_demo SET label = 'step2' WHERE id = 1;
ROLLBACK TO SAVEPOINT before_step2;
SELECT * FROM rollback_demo; -- step1
ROLLBACK; -- 例全体も取り消して before に戻す

PostgreSQLの例ではSAVEPOINT以降だけを取り消してトランザクションを続けられます。通常のROLLBACKは全体を終えます。SQL Serverなどはセーブポイントの構文が違うため、そのまま流用しません。

トランザクションの注意点

トランザクションを適切に管理するためには、いくつかの重要な注意点があります。これらのポイントを押さえることで、データベースの整合性を保ち、効率的なトランザクション管理が可能になります。

1. トランザクションの範囲を明確にする

トランザクションはできるだけ短く、必要最小限の操作を含むように設計しましょう。長時間にわたるトランザクションは、デッドロックやパフォーマンスの問題を引き起こす可能性があります。

2. 適切なエラーハンドリング

トランザクション内でエラーが発生した場合に備えて、ROLLBACKを適切に実行するようにしましょう。これにより、部分的な変更がデータベースに残ることを防ぎます。

3. 一貫性の維持

トランザクションはデータの一貫性を維持するために使用されます。複数の関連する操作を一つのトランザクションとして扱い、すべての操作が成功するか、またはすべて取り消されるように設計します。

4. 適切なロック管理

トランザクション中に必要なデータに対して適切なロックをかけ、他のトランザクションからの干渉を防ぎます。ただし、過剰なロックはパフォーマンスに影響を与えるため、バランスが重要です。

これらの注意点を踏まえてトランザクションを管理することで、安全で効率的なデータベース操作が可能になります。

まとめ

ROLLBACKは、データベース操作中に発生した誤りを取り消し、データの整合性を保つための重要な機能です。トランザクションを使用することで、複数の操作を一つの単位として扱い、全ての操作が成功した場合にのみ変更を確定できます。エラーが発生した場合はROLLBACKを使用してトランザクション全体を取り消し、安全にデータを管理することができます。これにより、データベースの信頼性と整合性を維持することが可能です。

ROLLBACKの使用方法とトランザクション管理のポイントを理解し、適切に活用することで、データベース操作の安全性を高めましょう。

ROLLBACKでは戻らないもの

COMMIT済みの更新、外部へ送ったメールやAPI処理などはROLLBACKでは取り消せません。MySQLではCREATE TABLEやALTER TABLEなど暗黙コミットするDDLがあり、非トランザクション対応テーブルも同様には戻せません。PostgreSQLでもシーケンス番号の消費は通常巻き戻らないため、欠番を必ず障害と見なさないでください。復旧はバックアップ、時点復旧、補償処理など別の設計になります。

公式資料:PostgreSQLのトランザクション/MySQLの暗黙コミット。例は説明用で、利用環境で実行検証していません。

この記事を書いた人

実務の現場で詰まりがちなポイントを地図にするITブログ「IT trip」を運営。Windows/Office(Teams・Excel)からSQL、サーバ運用、ガジェットまで、再現性のある手順と“なぜそうなるか”を丁寧に解説します。読んだらすぐ試せること、そして迷った人の次の一歩が見えることを大切にしています。

コメント

コメントする

目次