データベースを操作していると、「変更を確定する」「保存する」という操作が必要になります。そんなときに使われるのがSQLのCOMMIT
文です。
「COMMITって何のために使うの?」
「実行しないとどうなるの?」
といった疑問を持つ初心者の方も多いでしょう。
この記事では、COMMITの意味と役割、使い方、関連するトランザクション処理(ROLLBACKとの違い)まで、わかりやすく丁寧に解説します。
COMMITって何?基本を理解しよう

COMMITの役割
COMMITは、トランザクション中のすべての変更を確定するSQL文です。
一度実行すると、変更内容はデータベースに恒久的に保存され、元には戻せません。
基本的な書き方
COMMIT;
これだけです!とてもシンプルですね。
トランザクションとは?
COMMITを理解するために、まず「トランザクション」について説明します。
トランザクションとは、複数のSQL操作を一連の処理(単位)としてまとめる機能です。
すべてが成功したときのみデータを反映し、途中で問題があればキャンセル(ROLLBACK)できます。
身近な例で理解しよう
銀行の振込を例に考えてみましょう
- Aさんの口座から1万円を引く
- Bさんの口座に1万円を足す
この2つの操作は、どちらも成功するか、どちらも失敗するかでないと困りますよね。
途中で片方だけ成功して、もう片方が失敗したら、お金が消えたり増えたりしてしまいます。
-- 振込処理の例
START TRANSACTION; -- トランザクション開始
-- 1. Aさんの口座から1万円を引く
UPDATE accounts SET balance = balance - 10000 WHERE name = 'Aさん';
-- 2. Bさんの口座に1万円を足す
UPDATE accounts SET balance = balance + 10000 WHERE name = 'Bさん';
-- 両方成功したら確定
COMMIT;
COMMITの必要性
COMMITなしの場合
START TRANSACTION;
UPDATE products SET price = 1000 WHERE id = 1;
-- COMMITしないで終了
→ 変更が確定されず、データが元に戻ってしまう
COMMITありの場合
START TRANSACTION;
UPDATE products SET price = 1000 WHERE id = 1;
COMMIT; -- ここで変更が確定される
→ 変更がデータベースに保存される
COMMITの使い方と流れ

基本的なトランザクションの流れ
1. START TRANSACTION; -- または BEGIN;
2. (SQL操作を複数実行)
3. COMMIT; -- 成功時は確定
または ROLLBACK; -- 失敗時は取り消し
実際の使用例
商品購入処理
START TRANSACTION;
-- 1. 在庫を1個減らす
UPDATE products SET stock = stock - 1 WHERE id = 101;
-- 2. 売上記録を追加
INSERT INTO sales (product_id, quantity, sale_date)
VALUES (101, 1, NOW());
-- 3. 顧客のポイントを増やす
UPDATE customers SET points = points + 10 WHERE id = 5;
-- すべて成功したら確定
COMMIT;
ユーザー登録処理
START TRANSACTION;
-- 1. ユーザー情報を登録
INSERT INTO users (name, email, password)
VALUES ('田中太郎', 'tanaka@example.com', 'encrypted_password');
-- 2. プロフィール情報を登録
INSERT INTO profiles (user_id, age, gender)
VALUES (LAST_INSERT_ID(), 25, '男性');
-- 3. 初期設定を登録
INSERT INTO user_settings (user_id, theme, notification)
VALUES (LAST_INSERT_ID(), 'light', 1);
-- すべて成功したら確定
COMMIT;
データベース別の書き方
MySQL
START TRANSACTION; -- または BEGIN;
-- SQL操作
COMMIT;
PostgreSQL
BEGIN;
-- SQL操作
COMMIT;
SQL Server
BEGIN TRANSACTION;
-- SQL操作
COMMIT TRANSACTION; -- または COMMIT;
SQLite
BEGIN;
-- SQL操作
COMMIT;
COMMITとROLLBACKの違い
基本的な違い
操作 | 意味 | 使う場面 | 結果 |
---|---|---|---|
COMMIT | 変更を確定する | 正常に処理が完了したとき | データが保存される |
ROLLBACK | 変更を取り消す(元に戻す) | エラーが起きたとき | データが元の状態に戻る |
ROLLBACKの使用例
エラーが発生した場合
START TRANSACTION;
-- 1. ユーザーのポイントを減らす
UPDATE users SET points = points - 100 WHERE id = 5;
-- 2. 商品の在庫を確認
SELECT stock FROM products WHERE id = 10;
-- もし在庫が足りない場合...
-- エラーなので、1の処理も取り消し
ROLLBACK;
条件チェックで失敗した場合
START TRANSACTION;
-- 残高を確認
SELECT balance FROM accounts WHERE id = 1;
-- 残高:5000円
-- 10000円引き落とそうとする
UPDATE accounts SET balance = balance - 10000 WHERE id = 1;
-- 残高がマイナスになってしまう!
-- 処理を取り消し
ROLLBACK;
実際の業務での使い分け
成功パターン(COMMIT)
START TRANSACTION;
-- 注文処理
INSERT INTO orders (customer_id, total_amount) VALUES (123, 5000);
SET @order_id = LAST_INSERT_ID();
-- 在庫減算
UPDATE products SET stock = stock - 2 WHERE id = 1 AND stock >= 2;
-- 在庫が十分あったかチェック
IF ROW_COUNT() = 1 THEN
-- 支払い記録
INSERT INTO payments (order_id, amount) VALUES (@order_id, 5000);
COMMIT; -- 成功!
ELSE
ROLLBACK; -- 在庫不足で失敗
END IF;
自動コミットとは?

自動コミットの仕組み
多くのデータベースでは、「自動コミット」という機能があります。
これは、SQL文を1つ実行するたびに、自動的にCOMMITされる機能です。
自動コミットがONの場合
UPDATE users SET name = '田中太郎' WHERE id = 1;
-- 自動的にCOMMITされる(元に戻せない)
自動コミットがOFFの場合
UPDATE users SET name = '田中太郎' WHERE id = 1;
-- まだ確定されていない(ROLLBACKで戻せる)
COMMIT; -- 手動で確定する必要がある
自動コミットの設定確認と変更
MySQL
-- 現在の設定を確認
SELECT @@autocommit; -- 1=ON, 0=OFF
-- 自動コミットを無効にする
SET autocommit = 0;
-- 自動コミットを有効にする
SET autocommit = 1;
PostgreSQL
-- PostgreSQLでは手動トランザクションが基本
-- BEGINを使わなければ各文が自動コミットされる
いつ自動コミットを無効にすべき?
自動コミットOFFが良い場面
- 複数の操作をまとめて処理したい
- エラー時に安全に元に戻したい
- テスト環境でデータを確認してから確定したい
自動コミットONが良い場面
- 単発のデータ確認や簡単な更新
- 対話的にSQLを実行する場合
よくある間違いと注意点

COMMIT忘れによるロック
問題のある例
START TRANSACTION;
UPDATE products SET price = 2000 WHERE id = 1;
-- COMMITやROLLBACKを忘れて、セッションを閉じる
この場合、対象行がロックされたままになり、他のユーザーが同じデータを更新できなくなることがあります。
正しい例
START TRANSACTION;
UPDATE products SET price = 2000 WHERE id = 1;
-- 必ずCOMMITまたはROLLBACKで終了
COMMIT;
SELECT文にCOMMITは不要
間違った例
START TRANSACTION;
SELECT * FROM users;
COMMIT; -- SELECTだけなら不要
正しい例
-- データを変更する場合のみトランザクションが必要
START TRANSACTION;
UPDATE users SET last_login = NOW() WHERE id = 1;
COMMIT;
長時間のトランザクション
問題のある例
START TRANSACTION;
UPDATE large_table SET status = 'processing';
-- 長時間の処理(数分〜数時間)
-- 他のユーザーがテーブルにアクセスできない
COMMIT;
改善例
-- 処理を小分けにする
START TRANSACTION;
UPDATE large_table SET status = 'processing' WHERE id BETWEEN 1 AND 1000;
COMMIT;
START TRANSACTION;
UPDATE large_table SET status = 'processing' WHERE id BETWEEN 1001 AND 2000;
COMMIT;
エラーハンドリングを忘れる
問題のある例
START TRANSACTION;
UPDATE accounts SET balance = balance - 1000 WHERE id = 1;
UPDATE accounts SET balance = balance + 1000 WHERE id = 2;
-- エラーが起きても自動でROLLBACKされない場合がある
COMMIT;
安全な例(擬似コード)
try {
START TRANSACTION;
UPDATE accounts SET balance = balance - 1000 WHERE id = 1;
UPDATE accounts SET balance = balance + 1000 WHERE id = 2;
COMMIT;
} catch (error) {
ROLLBACK;
throw error;
}
実際の業務でのCOMMIT活用例
ECサイトの注文処理
START TRANSACTION;
-- 1. 注文データを登録
INSERT INTO orders (customer_id, order_date, total_amount)
VALUES (123, NOW(), 15000);
SET @order_id = LAST_INSERT_ID();
-- 2. 注文詳細を登録
INSERT INTO order_details (order_id, product_id, quantity, price)
VALUES (@order_id, 1, 2, 5000),
(@order_id, 2, 1, 5000);
-- 3. 在庫を減らす
UPDATE products SET stock = stock - 2 WHERE id = 1;
UPDATE products SET stock = stock - 1 WHERE id = 2;
-- 4. 顧客のポイントを増やす
UPDATE customers SET points = points + 150 WHERE id = 123;
-- 5. 在庫チェック(在庫がマイナスになっていないか)
SELECT COUNT(*) FROM products WHERE id IN (1, 2) AND stock < 0;
-- すべて正常なら確定
COMMIT;
バッチ処理での安全な大量更新
-- 毎日のポイント有効期限処理
START TRANSACTION;
-- 1. 期限切れポイントを特定
CREATE TEMPORARY TABLE expired_points AS
SELECT customer_id, SUM(points) as expired_points
FROM customer_points
WHERE expire_date < CURDATE()
GROUP BY customer_id;
-- 2. 顧客の総ポイントから減算
UPDATE customers c
JOIN expired_points e ON c.id = e.customer_id
SET c.total_points = c.total_points - e.expired_points;
-- 3. 期限切れポイントレコードを削除
DELETE FROM customer_points WHERE expire_date < CURDATE();
-- 4. ログに記録
INSERT INTO batch_logs (process_name, affected_rows, execute_date)
VALUES ('point_expiration', ROW_COUNT(), NOW());
COMMIT;
データ移行処理
-- 旧システムから新システムへのデータ移行
START TRANSACTION;
-- 1. ユーザーデータを移行
INSERT INTO new_users (id, name, email, created_at)
SELECT user_id, user_name, email_address, registration_date
FROM old_user_table
WHERE migration_flag = 0;
-- 2. 移行済みフラグを更新
UPDATE old_user_table
SET migration_flag = 1
WHERE migration_flag = 0;
-- 3. 移行ログを記録
INSERT INTO migration_logs (table_name, migrated_count, migration_date)
SELECT 'users', COUNT(*), NOW()
FROM new_users
WHERE created_at >= CURDATE();
COMMIT;
高度なトランザクション制御
セーブポイント(SAVEPOINT)
セーブポイントを使うと、トランザクション内で部分的なロールバックができます。
START TRANSACTION;
-- 1. ユーザー情報を更新
UPDATE users SET name = '新しい名前' WHERE id = 1;
-- セーブポイントを作成
SAVEPOINT update_profile;
-- 2. プロフィール情報を更新
UPDATE profiles SET bio = '新しい自己紹介' WHERE user_id = 1;
-- プロフィール更新でエラーが発生した場合
-- セーブポイントまで戻る(ユーザー名の更新は保持)
ROLLBACK TO update_profile;
-- 最終的に確定
COMMIT;
分散トランザクション
複数のデータベースにまたがる処理も可能です(高度な機能)。
-- データベース1での処理
START TRANSACTION;
UPDATE db1.accounts SET balance = balance - 1000 WHERE id = 1;
-- データベース2での処理
UPDATE db2.accounts SET balance = balance + 1000 WHERE id = 2;
-- 両方が成功した場合のみコミット
COMMIT;
パフォーマンスとCOMMIT

コミット頻度の最適化
悪い例:コミットが多すぎる
-- 10万件の処理で10万回コミット(遅い)
FOR i = 1 TO 100000 DO
START TRANSACTION;
INSERT INTO logs VALUES (i, 'data');
COMMIT;
END FOR;
良い例:適切なバッチサイズ
-- 1000件ずつコミット(早い)
FOR batch = 1 TO 100 DO
START TRANSACTION;
FOR i = (batch-1)*1000+1 TO batch*1000 DO
INSERT INTO logs VALUES (i, 'data');
END FOR;
COMMIT;
END FOR;
ロック時間の最小化
START TRANSACTION;
-- 必要なデータを先に取得
SELECT balance FROM accounts WHERE id = 1 FOR UPDATE;
-- 計算処理(時間がかかる場合は先に実行)
SET @new_balance = balance - 1000;
-- 更新処理(できるだけ短時間で)
UPDATE accounts SET balance = @new_balance WHERE id = 1;
-- すぐにコミット
COMMIT;
まとめ
COMMITは、データベースにおける「変更確定」の操作であり、トランザクション処理に不可欠な存在です。
ROLLBACKとの使い分けを理解し、必要に応じて手動でトランザクションを管理することで、より安全で柔軟なデータ操作が可能になります。
重要なポイント
- COMMIT:変更を確定する(元に戻せない)
- ROLLBACK:変更を取り消す(元に戻す)
- トランザクション:複数の操作をまとめて処理する仕組み
- 自動コミット:設定によって自動的にコミットされる機能
使い方のコツ
- 関連する複数の操作は必ずトランザクションでまとめる
- エラー処理を忘れずに実装する
- 長時間のトランザクションは避ける
- 必要に応じて自動コミットの設定を調整する
よく使う場面
- 金銭に関わる処理(振込、決済等)
- 在庫管理
- ユーザー登録
- データ移行
- バッチ処理
コメント