DDL语句一定会破坏当前事务,无例外;ALTER TABLE、DROP TABLE、CREATE INDEX、TRUNCATE TABLE、LOCK/UNLOCK TABLES、SET AUTOCOMMIT=1、START TRANSACTION、ANALYZE/OPTIMIZE TABLE及所有存储过程定义语句均触发隐式提交,导致此前DML已落库且ROLLBACK无效。
DDL 语句一定会破坏当前事务,没有例外,也不存在“把它包进事务就能回滚”的做法。
只要执行了以下任一语句,MySQL 就会立即提交当前事务(哪怕你刚 BEGIN 还没做任何 DML):
ALTER TABLE、DROP TABLE、CREATE INDEX、TRUNCATE TABLE
LOCK TABLES 和 UNLOCK TABLES
SET AUTOCOMMIT = 1(注意:设为 0 不触发,设为 1 才触发)START TRANSACTION(它本身会先隐式提交前一个事务)LOAD DATA INFILE、ANALYZE TABLE、OPTIMIZE TABLE
CREATE PROCEDURE、ALTER FUNCTION 等常见错误现象:在 Navicat 中勾选“自动提交”,又粘贴了一段含 ALTER TABLE 的脚本——结果前几条 INSERT 已落地,ROLLBACK 完全无效。
不能靠“我写了 BEGIN 就一定还在事务里”这种假设。运行时必须验证:
SELECT @@in_transaction,值为 1 才说明事务活跃SELECT TRX_ID, TRX_STATE FROM information_schema.INNODB_TRX WHERE TRX_MYSQL_THREAD_ID = CONNECTION_ID(),若返回空行或 TRX_STATE != 'RUNNING',事务已不在conn.get_autocommit() 和 conn.in_transaction 要一起看,单看一个容易误判接受它不可回滚的事实,再设计补偿路径,而不是硬塞进事务:
pt-online-schema-change 替代直接 ALTER TABLE:它不锁主表,失败自动清理,DML 不中断,适合线上大表ALTER TABLE 并确认成功;再开启新事务跑业务 DML;若 DML 失败,需人工或脚本补偿(比如新增字段可删,但删字段几乎无法回退)CREATE TABLE AS SELECT + RENAME TABLE:建新表、导数据、原子切换。但期间需停写或双写,复杂度高,仅适用于低流量时段真正容易被忽略的点是:很多 ORM 或迁移工具(如 Django migrate、Laravel migrate)底层会动态拼接 ALTER TABLE 并 EXECUTE,它们同样触发隐式提交——你看到“事务回滚”日志,其实只是回滚了 DDL 之后的操作。
Tplink企业版路由器WiFi名称的默认设置介绍(Tplink企业版路由器WiFi名称的默认设置是什么)
Tplink路由器灯常亮无法上网的原因分析(如何解决Tplink路由器灯常亮无法上网的问题)
Tplink千兆企业级路由器自动重启的作用和优势介绍(如何设置Tplink千兆企业级路由器自动重启功能)
一根天线的tplink路由器有哪些(一根天线的Tplink路由器的特点和优势介绍)
tplink路由器外网访问不了nas(Tplink路由器外网访问NAS的原因分析)
Tplink无法搜到路由器的原因分析(如何解决Tplink无法搜到路由器的问题)