rollback仅撤回当前未提交事务中的insert、update、delete操作,不回滚ddl、select、set等;在autocommit=1或隐式提交后无效,且受savepoint范围限制。

事务回滚(ROLLBACK)到底撤回哪些操作
回滚只对当前未提交的事务生效,且仅撤回该事务内执行的 INSERT、UPDATE、DELETE,不涉及 CREATE、DROP、ALTER 等 DDL 语句(它们会隐式提交)。如果执行了 SELECT 或 SET 变量,也不会被回滚——这些本身就不属于事务性变更。
常见误判场景:
- 在自动提交模式(
autocommit=1)下执行单条UPDATE后直接ROLLBACK,实际无效,因为语句已自动提交 - 事务中调用了存储过程,而过程内部含
COMMIT,会导致事务提前结束,后续ROLLBACK只影响它之后的语句 - 使用了
SAVEPOINT后回滚到某点,注意只能回滚到该保存点之后的操作,之前的部分仍保留
COMMIT 的不可逆性与隐式提交风险
COMMIT 一旦成功返回,修改就永久写入磁盘(取决于 innodb_flush_log_at_trx_commit 配置),无法通过数据库命令撤销。但更常被忽略的是“隐式提交”:以下操作会强制结束当前事务并自动提交,即使你没写 COMMIT:
- 执行
DDL语句(如CREATE TABLE、ALTER TABLE) - 执行
LOCK TABLES、UNLOCK TABLES - 执行
START TRANSACTION或BEGIN(会提交前一个事务) - 执行
mysql客户端的source命令加载 SQL 文件时,若文件含 DDL,也会触发隐式提交
这意味着,如果你在事务中先 UPDATE,再 CREATE TEMPORARY TABLE,那么 UPDATE 实际已在 CREATE 时提交,后续 ROLLBACK 对它无效。
如何确认当前是否处于事务中、以及 autocommit 状态
不能只靠记忆或代码注释判断事务状态。最可靠的方式是实时查系统变量:
齐博B2B系统是一款基于PHP程序和Mysql数据库为基础的开源B2B行业门户电子商务网站建站系统, 系统代码完整、开源,功能全面,架构优秀,提供良好的用户体验、及管理平台,是目前搭建B2B行业门户网站最好的程序之一。齐博B2B具有的功能特点包括:通行证整合功能通过通行证的整合,可以与流行的PHPWIND论坛或Discuz论坛以及Ucenter中心等进行通讯,从而为用户提供更多的交流场所,增加网站
SELECT @@autocommit, @@in_transaction;
其中:
-
@@autocommit = 1表示默认每条语句自动提交;设为0后需显式COMMIT/ROLLBACK -
@@in_transaction = 1表示当前连接有活跃事务(无论 autocommit 是 0 还是 1,只要执行过BEGIN或第一条 DML 就可能为 1)
注意:@@in_transaction 在 MySQL 5.7+ 才可用;低版本可用 SELECT TRX_ID FROM INFORMATION_SCHEMA.INNODB_TRX WHERE TRX_MYSQL_THREAD_ID = CONNECTION_ID() 辅助判断,但开销略大。
事务隔离级别对回滚/提交行为的影响
隔离级别不改变 COMMIT 和 ROLLBACK 的基本语义,但会影响“其他事务能否看到你的未提交变更”,进而影响业务逻辑中的判断依据。例如:
- 在
READ COMMITTED下,事务 A 修改某行后未提交,事务 B 查询不到该修改;但如果 A 提交了,B 后续查询立刻可见 - 在
REPEATABLE READ(InnoDB 默认)下,事务 B 第一次SELECT后,即使 A 提交了修改,B 再次SELECT仍看到快照数据——这容易让人误以为“A 的COMMIT没生效” -
SELECT ... FOR UPDATE或LOCK IN SHARE MODE会加锁,若此时被阻塞,ROLLBACK是释放锁的唯一方式,否则可能造成死锁或长等待
真正容易出问题的点在于:开发时本地用 READ UNCOMMITTED 测试,上线切到 REPEATABLE READ 后,原本依赖“读到未提交数据”的逻辑突然失效,而错误往往不报错,只表现为空数据或陈旧数据。









