MySQL可重复读隔离级别下开启事务的问题解决
作者:雨下的竹子
1.前言
在日常我们操作mysql时,mysql默认是自动提交的。当我们需要开启一个事务时,可以使用start transaction
或begin
命令,再使用commit
或rollback
提交或回滚事务。
但事务的使用也有一些注意事项,不注意的话,可能会带来意料之外的结果。
今天,我要分享的就是在Repeatable Read
(简称rr)隔离级别下,mysql的快照生成时机的问题。
2.问题引出
我们都知道,rr级别下,是根据快照来读取数据的,所以他能保证同一事务内的两次读取是一致的,不会因为其他事务提交的修改而导致前后读取结果不一样。
现在db3库下有个test表,且mysql隔离级别为rr(默认rr)。
开启两个会话,一个会话开启一个事务,另一个会话开启一个事务并修改一行数据
按正常理解来说,此时在第一个会话里查询数据,查询到的还是原来的’zhuzi1’而不是’zhuzin’
但实际上,我们却发现,第二个事务的修改影响到了第一个事务的结果。
3.原因
上面问题出现的原因,就是因为我们在开启一个事务时,并没有立即生成数据快照,而是在执行一次快照读(所谓快照读,就是我们平常使用的普通查询;当前读则是使用例如for update
加锁的查询)之后才生成的。所以,当我们在第一个事务中第一次执行快照读时,第二个事务已经提交修改了,当然是可以看到这个修改的。
mysql想要在开启事务时就生成快照,确保数据不再变化,可以使用如下方式开启事务
start transaction with consistent snapshot;
这样,mysql就会在开启事务时立即生成快照了。
官网对于with consistent snapshot
的介绍如下:
翻译的大致意思就是WITH CONSISTENT SNAPSHOT
修饰符为innodb启动一致读取。且只适用于innodb引擎。其效果与从任何InnoDB表中发出START TRANSACTION后接SELECT相同。WITH CONSISTENT SNAPSHOT修饰符不会更改当前事务隔离级别,因此只有当前隔离级别允许一致读取时,它才能提供一致的快照。唯一允许一致读取的隔离级别是可重复读取。对于所有其他隔离级别,WITH CONSISTENT SNAPSHOT子句将被忽略。忽略WITH CONSISTENT SNAPSHOT子句时会生成警告。
官网对rr的介绍如下:
由此可知,如果你开启了一个事务,却不进行一次读取操作,那么快照是不会建立的
到此这篇关于MySQL可重复读隔离级别下开启事务的一个注意事项的文章就介绍到这了,更多相关MySQL可重复读隔离开启事务内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!