SET AUTOCOMMIT = 1;
BEGIN;
INSERT INTO t1 VALUES (1);
CREATE TABLE t2 (pk INT PRIMARY KEY);
INSERT INTO t2 VALUES (2);
ROLLBACK;
SHOW TABLES;
結果: t1、t2 均存在,t1 中的 1 也插入成功!ROLLBACK 完全失效。
執行 CREATE TABLE 前,前一個事務被隱式提交。因 AUTOCOMMIT=1,提交後不再自動開啟新事務,後續 INSERT 立即提交,ROLLBACK 無事務可回滾。
SET AUTOCOMMIT = 0;
BEGIN;
INSERT INTO t1 VALUES (1);
CREATE TABLE t2 (pk INT PRIMARY KEY);
INSERT INTO t2 VALUES (2);
ROLLBACK;
SHOW TABLES;
結果: t1、t2 均存在,但 t1 有資料,t2 空表。原因:CREATE TABLE 觸發隱式 COMMIT(非 ROLLBACK),t1 的插入被提交;隨後新事務自動開啟(AUTOCOMMIT=0 語義),t2 的插入在新事務中,被 ROLLBACK 回滾。
為了保證直觀上的原子性。若不隱式提交,用戶期望
ROLLBACK同時撤銷INSERT與CREATE TABLE。但 DDL 背後涉及核心表更新、內存結構變更、存儲引擎文件創建等大量非事務性操作,工程上極難做到原子回滾,尤其在分布式系統中。
折中方案:約定 CREATE TABLE 等 DDL 預設提交前一個事務,即隱式提交。
MySQL 文檔顯示,隱式提交邏輯歷經多版本修正,並持續擴大觸發語句範圍(如 TRUNCATE、RENAME TABLE、DROP DATABASE 等),開發者需查閱對應版本文檔確認具體行為。
AUTOCOMMIT=0 並顯式控制 BEGIN/COMMIT/ROLLBACK,減少驚喜。