mysql中事务的自动提交与显式提交模式

来源:这里教程网 时间:2026-02-28 20:40:48 作者:

autocommit=1 时 insert 不生效?先确认当前会话模式

MySQL 默认开启自动提交(

autocommit=1
),但这个值可能被会话级修改,或在连接池、ORM 中被重置。执行
INSERT
后查不到数据,第一反应不该是“SQL 写错了”,而是检查当前事务状态:
SELECT @@autocommit;
返回
0
表示已关闭自动提交,此时所有 DML 都处于未提交事务中,除非手动
COMMIT
或断开连接(部分客户端会回滚)。常见陷阱是用命令行连上后执行了
SET autocommit = 0
,后续忘了恢复,导致看似“插入成功”实则未落盘。

显式事务中 COMMIT 和 ROLLBACK 的触发边界

显式事务以

BEGIN
START TRANSACTION
开始,以
COMMIT
ROLLBACK
结束。关键点在于:一旦执行了
COMMIT
,该事务内所有变更永久生效;而
ROLLBACK
仅回滚到最近一次
BEGIN
(或隐式事务起点),不是回滚整个会话历史。注意以下行为:

DDL 语句(如
CREATE TABLE
)在大多数存储引擎中会隐式触发
COMMIT
,导致前面未提交的 DML 一并提交
执行
SET autocommit = 1
会立即提交当前活跃事务(如果存在)
客户端异常断开且未设
wait_timeout
超时前,MySQL 通常会回滚未完成事务

Python pymysql / MySQLdb 中 autocommit 参数的实际作用

创建连接时传入

autocommit=True
,等价于连接建立后立刻执行
SET autocommit = 1
;设为
False
则默认进入手动提交模式。但要注意:

即使
autocommit=False
,调用
cursor.execute("INSERT ...")
也不会报错,只是暂存于事务中
必须显式调用
conn.commit()
才真正写入;忘记调用就断开连接,数据丢失
使用上下文管理器(
with conn:
)时,Python 的
mysqlclient
和较新版本
pymysql
会在退出时自动
commit
,但前提是没发生异常;有异常则
rollback
示例:
conn = pymysql.connect(autocommit=False)<br>cursor = conn.cursor()<br>cursor.execute("INSERT INTO t VALUES (1)")<br># 忘记 conn.commit() → 数据不会持久化

如何安全地临时关闭 autocommit 做批量操作

批量插入/更新时关掉

autocommit
能减少日志刷盘次数,提升性能,但风险也集中:一个出错可能导致整批失败。稳妥做法是:

START TRANSACTION
显式包裹操作,而非全局
SET autocommit = 0
控制单次事务数据量(如每 1000 行
COMMIT
一次),避免长事务阻塞 MVCC 清理
确保应用层捕获
IntegrityError
等异常并主动
ROLLBACK
,否则连接可能卡在未完成事务状态
不要依赖超时自动回滚——
innodb_lock_wait_timeout
控制锁等待,不控制事务生命周期
真正容易被忽略的是:某些中间件(如 ProxySQL、ShardingSphere)会拦截或改写
COMMIT
语句,开启事务后务必验证实际提交行为是否符合预期。

相关推荐