| この記事の要点 |
|
COMMIT とは
COMMIT はトランザクション中に行った変更をDBに永続化し、他のセッションから見えるようにする命令です。COMMIT 前の変更は自分のセッションでしか見えず、ROLLBACK で無効化できます。
基本構文
-- 標準SQL / MySQL / PostgreSQL
BEGIN;
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
COMMIT; -- 確定
-- SQL Server
BEGIN TRANSACTION;
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
COMMIT TRANSACTION; -- COMMIT TRAN でも可
-- Oracle
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
COMMIT; -- BEGIN は不要、DML 開始時に暗黙開始
-- COMMIT WORK は標準SQLの古い書き方(同義)
COMMIT WORK;
明示 COMMIT と暗黙 COMMIT
| 種類 | 発生条件 | 例 |
|---|---|---|
| 明示 COMMIT | アプリが COMMIT を実行 | COMMIT; |
| 暗黙 COMMIT (DDL) | DDL 実行時に自動 | CREATE / ALTER / DROP / TRUNCATE |
| 暗黙 COMMIT (制御) | セッション終了時 | 正常切断 (autocommit ON 時) |
| 暗黙 COMMIT (管理) | SET autocommit=1 等 | SET 文一部 / LOCK TABLES (MySQL) |
DDL の暗黙コミットの落とし穴
BEGIN;
INSERT INTO logs(msg) VALUES ('start');
CREATE TABLE tmp (id INT); -- ★ MySQL/Oracle ではここで暗黙 COMMIT
INSERT INTO logs(msg) VALUES ('mid');
ROLLBACK; -- もう start を消せない
-- PostgreSQL なら DDL もロールバック可能
BEGIN;
CREATE TABLE tmp (id INT);
ROLLBACK; -- tmp テーブルも消える
Autocommit と SET AUTOCOMMIT=0
-- MySQL
SELECT @@autocommit; -- 1 (ON) / 0 (OFF)
SET autocommit = 0; -- 明示 COMMIT モード
UPDATE accounts SET balance = 0 WHERE id = 1;
-- まだ COMMIT されていない。別セッションからは見えない
COMMIT; -- ここで初めて永続化
-- セッション内だけで OFF
SET SESSION autocommit = 0;
-- PostgreSQL の psql 対話モード
\set AUTOCOMMIT off
エラー時の自動ロールバック
多くのDBは、トランザクション中にエラーが発生すると以降のステートメントを拒否します。COMMIT を実行しても ROLLBACK 扱いになります(DB別に挙動差あり)。
-- PostgreSQL: 1つでもエラーが出るとトランザクションは ABORT 状態
BEGIN;
INSERT INTO users(id, name) VALUES (1, 'taro');
INSERT INTO users(id, name) VALUES (1, 'jiro'); -- 主キー重複エラー
SELECT 1; -- ERROR: current transaction is aborted
COMMIT; -- 実質 ROLLBACK
-- MySQL: エラーが出た文だけ無効。他の文は生きる
-- → 明示的に ROLLBACK 推奨
Two-Phase Commit (XA トランザクション)
複数のDBを1つの論理トランザクションとして扱うための仕組み。第1段階で全DBに「コミットできるか」を確認 (PREPARE)、全員OKなら第2段階で実際の COMMIT を実行します。
-- MySQL XA (例)
XA START 'tx1';
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
XA END 'tx1';
XA PREPARE 'tx1'; -- 第1段階: コミット可能性を保証
-- 別のDBでも同様の PREPARE を実行
XA COMMIT 'tx1'; -- 第2段階: 確定
-- 失敗時は XA ROLLBACK 'tx1';
-- Java EE / Spring の JTA で透明に利用可能
言語別 commit() メソッド
Java JDBC
Connection conn = DriverManager.getConnection(url, user, pass);
conn.setAutoCommit(false); // 明示 COMMIT モード
try {
PreparedStatement ps = conn.prepareStatement("UPDATE accounts SET balance = balance - ? WHERE id = ?");
ps.setBigDecimal(1, new BigDecimal("100"));
ps.setLong(2, 1L);
ps.executeUpdate();
conn.commit(); // 確定
} catch (SQLException e) {
conn.rollback(); // 巻き戻し
throw e;
} finally {
conn.close();
}
PHP PDO
$pdo = new PDO($dsn, $user, $pass, [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
]);
$pdo->beginTransaction();
try {
$pdo->prepare('UPDATE accounts SET balance = balance - ? WHERE id = ?')
->execute([100, 1]);
$pdo->commit(); // 確定
} catch (\Throwable $e) {
$pdo->rollBack();
throw $e;
}
Python (psycopg2 / sqlite3 / mysql-connector)
import psycopg2
conn = psycopg2.connect(dsn)
conn.autocommit = False # 既定で False
cur = conn.cursor()
try:
cur.execute("UPDATE accounts SET balance = balance - %s WHERE id = %s", (100, 1))
conn.commit() # 確定
except Exception:
conn.rollback()
raise
finally:
cur.close()
conn.close()
COMMIT のパフォーマンスチューニング
- 毎行 COMMIT は遅い: 1000 行 INSERT で 1000 fsync が走る
- バッチ COMMIT: 1000 行ごとに 1 COMMIT などで桁違いに高速
- WAL fsync を緩める(PostgreSQL
synchronous_commit=off)はクラッシュ時に最後の数秒消える覚悟が必要 - MySQL
innodb_flush_log_at_trx_commitも同様のトレードオフ(1: 安全 / 2: 速い / 0: 最速 危険)
FAQ
Q: COMMIT 後にやっぱり巻き戻したい
A: 不可能です。新しい UPDATE/DELETE で論理的に元に戻すか、バックアップから戻すしかありません。
Q: COMMIT 中にDBクラッシュしたら?
A: WAL/REDO ログから再起動時にロールフォワード or ロールバックされます。これがACIDのD(永続性)を保証する仕組みです。
Q: AUTOCOMMIT は ON / OFF どちらが良い?
A: 対話的SQLは ON のままで便利。アプリは明示 OFF + コードで COMMIT 制御が推奨。
子ページ
子ページはありません
人気ページ
- 1 Eclipseで「サーバーに追加または除去できるリソースがありません。」の原因と対処法
- 2 tomcat の起動 / 停止ログと catalina.log・catalina.out の違い
- 3 JavaScript で base URL を取得する方法|window.location.origin
- 4 YouTube Data API v3 エラー一覧|403・400・404 の原因と対処
- 5 Laravel エラー一覧|500/Blade/DB 接続/ルーティングの代表エラー
- 6 3Dグラフィックスとは|モデリング/レンダリング/主要ソフトウェア (Blender / Maya)
- 7 Spring Frameworkのアノテーション一覧
- 8 【Spring】@Valueアノテーションとは
- 9 CATALINA_HOME の確認方法 (Linux / Mac)
- 10 【Spring】@Autowiredアノテーションとは
最近更新/作成されたページ
- MariaDB Monitor (mysql コマンド) の使い方 2026-10-14 15:21:02
- MariaDB の管理ツール (phpMyAdmin / DBeaver 等) 2026-10-14 15:21:02
- Google Custom Search JSON API|新規受付終了・移行期限と既存実装の確認 2026-10-14 14:50:13
- MySQL rootの初期パスワード確認|導入方式・Docker既存DB・復旧の注意 2026-10-14 14:39:34
- MySQL root パスワードの変更方法(ALTER USER / mysqladmin / パスワード忘れ時の復旧) 2026-10-14 14:39:34
- MySQL ALTER USER の使い方|パスワード変更・アカウントロック 2026-10-14 14:39:34
- MySQL ERROR 1129|ホスト遮断の原因・カウンタ・解除前の確認 2026-10-14 14:04:49
- MySQL ERROR 1820・1862|期限切れパスワードの安全な更新と確認 2026-10-14 14:04:49
- MySQL ERROR 1698|ソケット認証・OSユーザー・接続経路の確認 2026-10-14 14:04:49
- mysql_configが見つからない|mysqlclientの旧ビルドとpkg-configの確認 2026-10-14 13:36:32
- MySQLエラー一覧|番号・SQLSTATE別の原因と安全な確認手順 2026-10-14 13:36:32
- インストール直後にNetbeansが反応しない 2026-10-14 13:07:02
- NetBeans でよくあるエラー一覧と対処法 — JDK / Tomcat / PHP / メモリ不足 2026-10-14 13:07:02
- Apache NetBeans入門|起動JDK・プロジェクト作成・関連手順 2026-10-14 13:07:02
- 【Laravel】ページング(ページネーション)をする方法 2026-10-14 12:31:44