事务未提交时数据对其他会话不可见
MySQL 默认隔离级别是
REPEATABLE READ,未提交的事务修改只在当前会话内可见。其他会话查不到这些变更,也不会被阻塞(除非涉及行锁冲突)。这常被误认为“没影响”,其实已悄悄占用资源。 未提交事务会持续持有行锁或间隙锁,可能造成其他会话
UPDATE或
SELECT ... FOR UPDATE阻塞
INFORMATION_SCHEMA.INNODB_TRX中能看到该事务状态为
RUNNING,且
TRX_STATE是
ACTIVE长时间未提交会拖慢
purge线程,导致
undo log无法及时回收,
ibdata1文件持续膨胀
连接断开后未提交事务自动回滚
MySQL 客户端异常断连(比如网络中断、应用崩溃、超时断开),服务端检测到连接关闭后,会立即执行隐式回滚。这点和 Oracle 不同——Oracle 断连后事务仍保持活跃,直到被杀或超时。
可通过SHOW VARIABLES LIKE 'wait_timeout'和
interactive_timeout查看超时阈值,默认 28800 秒(8 小时) 若应用使用连接池(如 HikariCP),需确认是否开启
connection-test-query或
validation-timeout,避免拿到已失效但未清理的连接 注意:
mysql -e "UPDATE t SET x=1;"这类单命令执行完即退出,事务不会自动提交——除非显式加
-e "START TRANSACTION; UPDATE ...; COMMIT;"
autocommit=0 时忘记 COMMIT 是最常见一致性破环点
当会话执行过
SET autocommit = 0,后续所有 DML 都进入手动事务模式。此时即使只执行一条
UPDATE,不
COMMIT或
ROLLBACK,就等于挂起一个未决事务。 典型表现:
SELECT能看到刚改的值,但其他会话查不到;应用重启后该修改彻底消失 开发调试时常用
mysql -u root -p --init-command="SET autocommit=0",极易遗忘
COMMIT建议在连接初始化时统一设为
autocommit=1,仅在明确需要多语句原子性时用
BEGIN/
COMMIT
长事务导致 MVCC 快照过旧与主从延迟加剧
未提交事务越久,其事务 ID 越“老”,InnoDB 为维持一致性读(consistent read),必须保留早于该事务开始的所有版本记录。这直接拖累 purge 效率,并放大主从延迟。
主库上长事务会让show master status的
File和
Position滞后,因为 binlog 只在
COMMIT时写入 从库 SQL 线程等待主库该事务提交后才能继续,表现为
Seconds_Behind_Master持续增长 监控关键指标:
SELECT TRX_ID, TRX_STARTED, TIME_TO_SEC(NOW() - TRX_STARTED) AS duration FROM INFORMATION_SCHEMA.INNODB_TRX ORDER BY duration DESC LIMIT 5;
事务没提交这事本身不报错,但它像后台静默运行的定时器——锁、日志、快照、复制链路,全在悄悄承压。最容易被忽略的是:你以为只是“还没点保存”,系统却已在底层扛着整个一致性模型往前挪。
