autocommit=1时,BEGIN仅临时将当前会话autocommit设为0,并不自动开启持久事务;后续语句仍自动提交,除非显式COMMIT或ROLLBACK,且连接断开时自动回滚。

autocommit=1 时,BEGIN 真的开启事务了吗?
开了 autocommit=1(默认),执行 BEGIN 后确实进入事务状态,但这个“开启”只是标记起点,不是魔法开关。后续每条语句仍会自动提交——除非你显式写 COMMIT 或 ROLLBACK。
-
BEGIN只是把autocommit临时设为 0,仅对当前会话有效;一旦COMMIT或ROLLBACK,它又自动切回 1 - 如果只写
BEGIN不跟COMMIT,连接断开或超时后,MySQL 会自动ROLLBACK,数据不会残留 - 用客户端工具(如 MySQL Workbench)执行
BEGIN后直接关窗口,很容易误以为“事务还在”,其实早已回滚
为什么 INSERT 没报错却没进库?查 autocommit 状态
常见现象:执行完 INSERT 看返回 Query OK,但另一会话查不到新数据。大概率是当前会话 autocommit=0,且没 COMMIT。
- 查当前值:
SELECT @@autocommit;—— 返回 0 就是手动事务模式 - 临时切回自动提交:
SET autocommit = 1;,之后所有语句立刻生效 - 注意:应用层(如 Python 的
pymysql)可能默认关闭autocommit,得看驱动文档,不能只信 MySQL 默认值
Java JDBC 中 connection.setAutoCommit(false) 的真实影响
调用 setAutoCommit(false) 不等于“开启一个事务”,它只是禁用自动提交,真正的事务边界仍由第一条 DML(如 UPDATE)触发。
- 在
setAutoCommit(false)后执行SELECT,不启动事务,也不加锁 - 第一条
UPDATE才真正开启事务,此时才产生transaction id,才开始记录 undo log - 如果一直只读不写,连接保持
autocommit=false状态,但 InnoDB 并不认为你在事务里,也不会占用事务视图资源 - 务必配对使用
commit()或rollback(),否则连接归还连接池时可能卡住事务,拖慢整个池
START TRANSACTION 和 BEGIN 有区别吗?
没有本质区别。MySQL 文档明确说 BEGIN 是 START TRANSACTION 的别名,二者完全等价,都只是把 autocommit 设为 0 并初始化事务上下文。
- 别被名字误导:
BEGIN不代表“事务从此开始持续存在”,它不提供嵌套、不支持保存点(savepoint 是另一回事) - 想加一致性读?得靠
SELECT ... FOR UPDATE或SELECT ... LOCK IN SHARE MODE,不是靠BEGIN本身 - 某些 ORM(如 Django)内部用
START TRANSACTION,而老脚本爱写BEGIN,混用完全没问题,MySQL 不区分
事务不是开关,是状态机。autocommit 控制的是“语句级提交时机”,而 BEGIN / START TRANSACTION 只是切换这个控制权的快捷方式。最容易忽略的,是应用层连接池对 autocommit 状态的复用逻辑——一次忘记 commit,可能让下个请求在别人的事务里写数据。


















