首页/数据/SQL 速查/autocommit 行为差异
变更与事务52 条

autocommit 行为差异

MySQL 默认 autocommit=1(每条语句自动提交);PostgreSQL 没有该开关,天然“每条语句一个隐式事务”,除非显式 BEGIN。

SQL 速查数据更新于 2026-10-13

autocommit 是什么

MySQL 默认 autocommit = 1,每条语句执行完立即提交;关闭后多条语句会落进同一个事务,直到显式 COMMIT 或 ROLLBACK。PostgreSQL 没有这个开关,天然是每条独立语句一个隐式事务,要把语句绑成一个事务必须显式写 BEGIN。

基本信息

MySQL 默认autocommit = 1,每条语句独立提交
MySQL 关闭SET autocommit = 0 后语句进入同一事务,需显式提交
PostgreSQL没有 autocommit 变量;BEGIN 之后才进入事务块
连接池归还连接前必须确保事务已提交或已回滚
作用范围autocommit 按会话生效,不要指望改一次就永久生效
DDL 影响MySQL 中 DDL 会隐式提交当前事务

MySQL 事务边界

MySQL 事务边界
SELECT @@autocommit;        -- 1:默认每条语句自动提交
SET autocommit = 0;         -- 关闭后语句进入同一事务
INSERT INTO t VALUES (1);
UPDATE t SET a = 2 WHERE id = 1;
COMMIT;                     -- 必须显式提交,否则连接断开就白做
SET autocommit = 1;         -- 用完恢复原值,连接池环境尤其重要

PostgreSQL 事务边界

PostgreSQL 事务边界
SHOW transaction_isolation;   -- 查看当前隔离级别
BEGIN;
UPDATE t SET a = 2 WHERE id = 1;
COMMIT;                       -- 没有 autocommit 开关,事务边界全靠 BEGIN 与 COMMIT

行为对照

维度MySQL 8PostgreSQL
默认模式autocommit = 1每条语句隐式自动提交
显式事务START TRANSACTION 或 BEGINBEGIN
变量开关有 @@autocommit没有对应变量
DDL 行为会隐式提交当前事务多数 DDL 可在事务内回滚
连接池风险未提交事务随连接归还而挂起长时间 idle in transaction

典型使用场景

  • 批量写入:把多条 INSERT 放进同一事务减少提交次数
  • 数据修复脚本:多张表联动修改,要么全成要么全退
  • 资金类操作:扣款与入账必须在同一个事务里
  • 连接池排查:找出处于未提交状态的连接
  • 临时关闭自动提交做数据比对,比对完直接回滚
  • 迁移与补数:小批量分批提交,兼顾性能与可恢复性
autocommit 是会话级的:在连接池里 SET autocommit = 0 之后归还连接,下一位使用者拿到的可能就是关着自动提交的连接,因此修改后必须恢复原值。
忘了提交的代价很实在:未提交事务会一直持锁、阻止清理(MySQL 的 purge、PG 的 vacuum),表象是“库越来越慢”,根因却是一条没人管的悬挂事务。

易错点

  • 关闭 autocommit 后忘记提交:连接归还后事务仍挂着,持锁并阻止清理
  • 以为 PG 也有 autocommit:没有这个开关,必须写 BEGIN 才能把多条语句绑成一个事务
  • 在 MySQL 里靠 autocommit = 0 保护 DDL:DDL 会隐式提交当前事务,保护并不成立
  • 在连接池里改会话参数后不恢复:后续使用者拿到非默认配置,出现难以复现的行为差异

数据来源与参考

  • MySQL 8.0 Reference Manual · Server System Variables
  • PostgreSQL Documentation · Transactions
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌