快捷搜索:  朋友圈  as  伪静态  次数  响应式  虎牙  浏览数  anniu

咦,为什么我的事务回滚不了?

MySQL 事务小伙伴们都懂通过 begin 开启事务通过 commit 提交事务或者通过 rollback 回滚事务。

在前面的文章中松哥也和大家聊了一些事物原理以及相关的细节小伙伴们可以回顾一下

MVCC 水略深但是弄懂了真的好爽一致性视图是啥时候建立的四个案例看懂 MySQL 事务隔离级别

正常来说当我们开启一个事务之后需要 commit 或者 rollback 来结束一个事务的但是有时候一些操作会自动帮我们提交事务如果大家不了解隐式事务的话那么在具体使用事务的事务可能就会遭遇一些莫名其妙的问题。

1. DDL 操作

首先一点就是 DDL 操作会隐式提交事务这个松哥在之前的文章中其实有说过我们再来一起回顾下

所有的 DDL 语句都会导致事务隐式提交换句话说当你在执行 DDL 语句前事务就已经提交了。这就意味着带有 DDL 语句的事务将来没有办法 rollback。

我举一个简单的例子大家一起来看下

我们来一起看下我这里的测试逻辑

首先查询总记录数有四条。开启一个事务。执行一条删除语句。alter 表新增一个字段。回滚。再次查询数据。

到第六步的时候我们发现查询到的数据只剩三条了说明第五步的回滚并没有生效。原因就在于执行 alter 之前事务已经被隐式提交了。

所以小伙伴们在日常开发中最好不要在事务中混有 DDL 语句DDL 语句和 DML 语句分开写。

对于上面的案例如果大家去掉第四步的 alter那么回滚是可以回滚成功的这个小伙伴们自己来测试我就不演示了。

当然 DDL 操作可不仅仅是 alter其他的如 CREATE、DROP 等操作也会导致事务隐式提交这里松哥就不一一举例了小伙伴们可以自行尝试。

2. DCL 操作

DDL 和 DML 大家应该经常接触到但是 DCL 可能有小伙伴不清楚DCL 其实就是 Data Control Language中文译作数据控制语言我们日常授权或者回收数据库上的权限所使用的 GRANT、REVOKE 等就算是 DCL 操作。

我举个简单例子

可以看到跟第一小节的测试步骤一样只不过第四步换成一个 GRANT 语句那么最终的事务回滚也会失效原因就在于事务已经提交了。

当然除了 GRANT 和 REVOKE 之外其他的创建、更新或者删除用户的操作也会导致事务隐式提交。主要有

CREATE USER…DROP USER…ALTER USER…SET PASSWORD…

3. 新事务开启

一个事务还没提交结果你又开启了一个新的事务那么此时前一个事务也会隐式提交。看个例子

这个好理解不多说。

您可能还会对下面的文章感兴趣: