必须关闭autocommit(set autocommit = 0)才能实现事务可控,否则commit/rollback无效;确认状态应执行select @@autocommit,返回0表示关闭,1表示开启,默认为1且为会话级变量。

autocommit 关闭后,事务才真正可控——不关它,COMMIT 和 ROLLBACK 基本无效,所谓“一致性”只是幻觉。
怎么确认当前 autocommit 状态
别猜,直接查。执行:
SELECT @@autocommit;返回
1 表示开启(默认),0 表示关闭。注意:@@autocommit 是会话级变量,不同连接互不影响;全局设置需加 GLOBAL,但普通用户通常无权限。
- 只对当前连接生效:用
SET autocommit = 0; - 想让新连接也默认关闭?得改配置文件
my.cnf,加一行autocommit=0,但生产环境极少这么干——容易误伤其他应用逻辑 - MySQL 8.0 不再支持旧变量名
tx_isolation,同理,也别用已废弃的SET AUTOCOMMIT ON/OFF写法,只认=0或=1
关闭 autocommit 后事务必须显式结束
关了 autocommit,每条 INSERT/UPDATE/DELETE 都会滞留在未提交状态,直到你发 COMMIT 或 ROLLBACK。
常见错误现象:
— 执行完几条更新,查表发现没变 → 忘了 COMMIT
— 突然断开连接,数据“消失” → MySQL 自动回滚未提交事务,不是丢数据,是根本没提交过
- 用
START TRANSACTION或BEGIN开启事务后,autocommit会临时失效,但事务结束后自动恢复原值(比如之前是1,事务完还是1) - 所以不要依赖
BEGIN来“代替”关autocommit;它只管单次事务,而关autocommit是为整段业务逻辑铺路 - DDL 语句(如
ALTER TABLE)仍会强制触发隐式提交,哪怕autocommit=0—— 这点极易被忽略
为什么关 autocommit 才能保障一致性
一致性(Consistency)不是靠隔离级别或日志保证的,而是靠“多步操作要么全成、要么全退”这个原子边界。而这个边界,只有在 autocommit=0 下才能由你亲手划定。
例如转账:UPDATE accounts SET balance = balance - 100 WHERE id = 1;UPDATE accounts SET balance = balance + 100 WHERE id = 2;
如果中间出错(比如第二条因约束失败),第一条已自动提交 → 金额不守恒。关掉 autocommit,两条都在同一事务里,ROLLBACK 就能兜底。
- 仅靠
REPEATABLE READ隔离级别不能防止这类逻辑不一致 - InnoDB 是唯一默认支持事务的引擎;若表用的是
MyISAM,关autocommit也没用 —— 先SHOW CREATE TABLE xxx;确认引擎 - 长事务会持锁、占内存、拖慢复制延迟,
autocommit=0后务必配超时检查或监控INFORMATION_SCHEMA.INNODB_TRX
关键点其实就一个:关 autocommit 不是目的,是把事务控制权从 MySQL 手里拿回来。一旦忘了 COMMIT,或者误在事务里执行了 DDL,一致性反而更脆弱。











