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 8 | PostgreSQL |
|---|---|---|
| 默认模式 | autocommit = 1 | 每条语句隐式自动提交 |
| 显式事务 | START TRANSACTION 或 BEGIN | BEGIN |
| 变量开关 | 有 @@autocommit | 没有对应变量 |
| DDL 行为 | 会隐式提交当前事务 | 多数 DDL 可在事务内回滚 |
| 连接池风险 | 未提交事务随连接归还而挂起 | 长时间 idle in transaction |
典型使用场景
- 批量写入:把多条 INSERT 放进同一事务减少提交次数
- 数据修复脚本:多张表联动修改,要么全成要么全退
- 资金类操作:扣款与入账必须在同一个事务里
- 连接池排查:找出处于未提交状态的连接
- 临时关闭自动提交做数据比对,比对完直接回滚
- 迁移与补数:小批量分批提交,兼顾性能与可恢复性
autocommit 是会话级的:在连接池里 SET autocommit = 0 之后归还连接,下一位使用者拿到的可能就是关着自动提交的连接,因此修改后必须恢复原值。
忘了提交的代价很实在:未提交事务会一直持锁、阻止清理(MySQL 的 purge、PG 的 vacuum),表象是“库越来越慢”,根因却是一条没人管的悬挂事务。