最近在阅读一篇关于隔离级别的文章,文章中提到了一种场景,我们下面来分析一下。
文章目录
- 1、实验环境
- 2、两个实验的语句执行顺序
- 3、关于start transaction和start transaction with consistent snapshot
- 4、实验结果解释
- 4.1、实验1
- 4.2、实验2
- 4.3、调整实验1,达到和实验2一样的效果
1、实验环境
版本:5.7.30-log
隔离级别:RR
2、两个实验的语句执行顺序
3、关于start transaction和start transaction with consistent snapshot
这篇文章讨论的问题是start transaction和start transaction with consistent snapshot这两条命令的区别。
start transaction:开启事务,但只有发生第一条和InnoDB有关系的sql语句时,事务才开始生效。也就是说单独执行start transaction并不会开启事务,只有执行一条sql语句才可以,select语句都行。
start transaction with consistent snapshot:开启一致性快照读,这个命令的含义就相当于执行start transaction后紧接着执行一条select,意思是立即开启事务。
4、实验结果解释
能理解到这一层,上面的案例就很好理解了,我们来讨论一下。
4.1、实验1
实验1中,事务A和事务B的语句执行顺序为:
事务B:select
事务A:start transaction(此时,事务A并没有开启事务)
事务B:insert(事务B是一个自动事务,执行完即提交)
事务A:select(真正开启事务)
此时事务A是能查询到事务B新增的数据的。因为在事务A真正开启事务之前,事务B已经提交了,事务A开启事务时,肯定是能读取到其他事务已提交的结果的
4.2、实验2
实验2中,事务A和事务B的语句执行顺序为:
事务B:select
事务A:start transaction with consistent snapshot(事务A开启事务)
事务B:insert(事务B是一个自动事务,执行完insert即提交)
事务A:select
此时事务A就不能读取到事务B新增的数据,这是InnoDB不可重复读所做的事情
4.3、调整实验1,达到和实验2一样的效果
实验1,调整一下事务A语句的执行顺序,就不会读取到事务B的新增数据了。
事务B:select
事务A:start transaction(此时,事务A并没有开启事务)
事务A:select(真正开启事务)
事务B:insert(事务B是一个自动事务,执行完insert即提交)
事务A:select(事务A在事务B执行insert前已经开启事务,因为RR隔离级别下不可重复读的原因,所以就读取不到事务B新增的数据)