データベースを扱っていて、こんな経験はありませんか?
- 「間違ってUPDATEしてしまった…」
- 「途中でエラーが出て、処理が中途半端になった…」
- 「複数のテーブルを一度に更新したいけど、失敗したら全部元に戻したい」
そんなときに役立つのがROLLBACK(ロールバック)です。
データベースを扱う上で避けて通れないのが「トランザクション制御」です。
ROLLBACKは、データの変更を安全に取り消すために使う重要な機能です。
この記事では、SQLのROLLBACKの意味、使い方、COMMITとの関係、実務での注意点などを、初学者でも理解しやすい形で解説します。
ROLLBACKとは?

簡単に言うと
ROLLBACK
は、SQLのトランザクション制御文のひとつで、未確定の変更(INSERT・UPDATE・DELETEなど)をキャンセルして元の状態に戻すために使います。
身近な例で考えてみよう
ROLLBACKは「操作の取り消し(Ctrl+Z)」のようなものです。
- Word文書:間違って文字を削除 → Ctrl+Zで元に戻す
- データベース:間違ってデータを削除 → ROLLBACKで元に戻す
基本的な構文
ROLLBACK;
たったこれだけで、トランザクション内で行った変更をすべて取り消せます。
ROLLBACKが使われる場面
場面 | 例 | ROLLBACKの効果 |
---|---|---|
操作ミス | 間違ったデータを更新 | 更新前の状態に戻す |
エラー発生 | 途中で処理が失敗 | 処理開始前の状態に戻す |
テスト実行 | データ変更のテスト | テスト前の状態に戻す |
バッチ処理 | 大量処理の途中で問題発生 | 処理開始前の状態に戻す |
トランザクションとCOMMITの関係

トランザクションって何?
トランザクションとは、ひとまとまりの処理単位のことです。
「全て成功するか、全て失敗するか」が原則で、これを原子性といいます。
銀行振込の例で理解しよう
振込処理 = 1つのトランザクション
1. A口座から10,000円を引く
2. B口座に10,000円を入れる
もし途中で失敗したら:
- ❌ A口座だけお金が減る → 困る!
- ⭕ 全部なかったことにする(ROLLBACK) → 安全!
基本的なトランザクション制御
コマンド | 役割 | タイミング |
---|---|---|
BEGIN または START TRANSACTION | トランザクション開始 | 処理の最初 |
COMMIT | 変更を確定(保存) | すべて成功した時 |
ROLLBACK | 変更を破棄(取り消し) | 問題が発生した時 |
実例:銀行振込のSQL
-- トランザクション開始
BEGIN;
-- A口座から10,000円を引く
UPDATE accounts SET balance = balance - 10000 WHERE account_id = 'A001';
-- B口座に10,000円を入れる
UPDATE accounts SET balance = balance + 10000 WHERE account_id = 'B001';
-- 成功の場合:変更を確定
COMMIT;
-- 失敗の場合:変更を取り消し
-- ROLLBACK;
処理の流れ
1. BEGIN → トランザクション開始
2. UPDATE → データ変更(仮の状態)
3. UPDATE → データ変更(仮の状態)
4. COMMIT → 変更を正式に保存
または
ROLLBACK → すべての変更を取り消し
ROLLBACKの実践的な使い方
使いどころ1:バッチ処理でのエラー対応
BEGIN;
-- 大量のデータを処理
UPDATE products SET price = price * 1.1; -- 価格を10%アップ
-- 処理件数を確認
SELECT COUNT(*) FROM products WHERE updated_at > NOW() - INTERVAL 1 MINUTE;
-- 予想と違う場合は取り消し
-- ROLLBACK;
-- 問題なければ確定
-- COMMIT;
使いどころ2:データ移行での安全確認
BEGIN;
-- 古いテーブルから新しいテーブルにデータをコピー
INSERT INTO new_customers
SELECT customer_id, name, email FROM old_customers;
-- データ件数を確認
SELECT
(SELECT COUNT(*) FROM old_customers) AS old_count,
(SELECT COUNT(*) FROM new_customers) AS new_count;
-- 件数が一致すればCOMMIT、そうでなければROLLBACK
使いどころ3:テスト環境でのデータ確認
BEGIN;
-- テスト用にデータを変更
UPDATE users SET status = 'premium' WHERE user_id = 123;
-- 結果を確認
SELECT * FROM users WHERE user_id = 123;
SELECT * FROM user_benefits WHERE user_id = 123;
-- テスト完了後、必ず元に戻す
ROLLBACK;
重要な注意点

1. COMMITした後はROLLBACKできない
BEGIN;
UPDATE users SET name = '新しい名前' WHERE id = 1;
COMMIT; -- ここで確定される
ROLLBACK; -- ❌ これは効果なし!
2. 自動コミットに注意
データベース | デフォルト設定 | 対策 |
---|---|---|
MySQL | 自動コミット = ON | START TRANSACTION を使う |
PostgreSQL | 自動コミット = OFF | そのまま使える |
SQLite | 自動コミット = ON | BEGIN を使う |
MySQLでの正しい使い方:
-- 自動コミットを無効にする方法1
START TRANSACTION;
UPDATE users SET name = 'test';
ROLLBACK;
-- 自動コミットを無効にする方法2
SET autocommit = 0;
UPDATE users SET name = 'test';
ROLLBACK;
3. DDL(データ定義言語)の扱い
操作 | ROLLBACKできる? | 例 |
---|---|---|
INSERT, UPDATE, DELETE | ⭕ できる | データの変更 |
CREATE TABLE | △ データベース依存 | テーブル作成 |
DROP TABLE | △ データベース依存 | テーブル削除 |
ALTER TABLE | △ データベース依存 | テーブル構造変更 |
データベースごとのROLLBACK対応状況
主要データベースの比較
データベース | ROLLBACK対応 | DDLのトランザクション | 特徴 |
---|---|---|---|
PostgreSQL | ⭕ 完全対応 | ⭕ DDLもトランザクション可 | 最も安全 |
MySQL | ⭕ InnoDBのみ | ❌ 一部DDLは自動コミット | ストレージエンジンに注意 |
SQLite | ⭕ 対応 | △ 制限あり | 軽量だが機能制限 |
Oracle | ⭕ 完全対応 | ⭕ 基本的に対応 | エンタープライズ級 |
SQL Server | ⭕ 完全対応 | ⭕ 対応 | Windows環境に最適 |
MySQL利用時の重要な注意点
InnoDBを使う:
-- テーブル作成時にInnoDBを指定
CREATE TABLE users (
id INT PRIMARY KEY,
name VARCHAR(100)
) ENGINE=InnoDB;
-- 現在のストレージエンジンを確認
SHOW TABLE STATUS WHERE Name = 'users';
実務での活用パターン
パターン1:プログラムでのエラーハンドリング
-- Python(擬似コード)の例
try:
cursor.execute("BEGIN;")
cursor.execute("UPDATE accounts SET balance = balance - 100 WHERE id = 1;")
cursor.execute("UPDATE accounts SET balance = balance + 100 WHERE id = 2;")
# 残高チェック
cursor.execute("SELECT balance FROM accounts WHERE id = 1;")
if cursor.fetchone()[0] < 0:
raise Exception("残高不足")
cursor.execute("COMMIT;")
except Exception as e:
cursor.execute("ROLLBACK;")
print(f"エラーが発生しました: {e}")
パターン2:手動での安全確認
-- 手順1:トランザクション開始
BEGIN;
-- 手順2:変更実行
UPDATE products SET price = price * 0.9 WHERE category = 'electronics';
-- 手順3:結果確認
SELECT category, COUNT(*), AVG(price) FROM products
WHERE category = 'electronics'
GROUP BY category;
-- 手順4:問題なければCOMMIT、問題があればROLLBACK
-- COMMIT; または ROLLBACK;
パターン3:複雑な処理の段階的確認
BEGIN;
-- ステップ1:マスターデータ更新
UPDATE categories SET tax_rate = 0.10 WHERE type = 'food';
SELECT COUNT(*) as updated_categories FROM categories WHERE tax_rate = 0.10;
-- ステップ2:商品価格の再計算
UPDATE products p
JOIN categories c ON p.category_id = c.id
SET p.final_price = p.base_price * (1 + c.tax_rate)
WHERE c.type = 'food';
-- ステップ3:結果確認
SELECT
COUNT(*) as total_products,
AVG(final_price) as avg_final_price
FROM products p
JOIN categories c ON p.category_id = c.id
WHERE c.type = 'food';
-- 問題なければCOMMIT
COMMIT;
よくある間違いと対策

間違い1:トランザクションを開始し忘れ
-- ❌ 悪い例
UPDATE users SET status = 'inactive';
ROLLBACK; -- 効果なし(自動コミットされている)
-- ⭕ 良い例
BEGIN;
UPDATE users SET status = 'inactive';
ROLLBACK; -- 正しく取り消される
間違い2:COMMITとROLLBACKの両方を実行
-- ❌ 悪い例
BEGIN;
UPDATE users SET name = 'test';
COMMIT;
ROLLBACK; -- 意味がない
-- ⭕ 良い例
BEGIN;
UPDATE users SET name = 'test';
-- 条件に応じてどちらか一つだけ実行
-- COMMIT; または ROLLBACK;
間違い3:長時間のトランザクション
-- ❌ 悪い例(長時間ロックが続く)
BEGIN;
UPDATE large_table SET status = 'processing'; -- 100万件
-- 30分かかる重い処理...
COMMIT;
-- ⭕ 良い例(バッチに分割)
-- 1万件ずつ処理して、こまめにCOMMIT
まとめ:ROLLBACKで安全なデータベース操作を
重要なポイント
- ROLLBACKはトランザクション内の変更を取り消す重要な機能
- COMMITとの組み合わせでデータの整合性を保つ
- データベースごとに対応状況が異なるので事前確認が必要
- 自動コミット設定に注意して使う
安全な操作の流れ
- BEGINでトランザクション開始
- データ変更の実行
- 結果確認(件数、内容など)
- 判断:問題なければCOMMIT、問題があればROLLBACK
覚えておきたいベストプラクティス
場面 | 対応 |
---|---|
重要なデータ変更 | 必ずトランザクションを使う |
バッチ処理 | エラーハンドリングでROLLBACK |
テスト実行 | 必ずROLLBACKで元に戻す |
本番環境 | 事前にテスト環境で動作確認 |
コメント