RC、RR隔离级别下快照读的异同

在上一篇文章我向大家介绍了MVCC的实现原理,现在我们来看一下RR、RC级别下的快照读

RC(读已提交)
我们都知道RC能够解决脏读(读到未提交的数据),那么是怎么实现的呢?

事务A 事务B
开启事务 开启事务
快照读,a=500 快照读,a=500
更新为a=400
提交事务

当事务A的事务提交完的时候,事务B再次去快照读,我们可以发现此时读出来的数据为a=400。那这是为什么呢?其实是这样的,当事务A还未提交的时候,事务B第一次快照读的Read View中,事务A为正在活跃是事务,所以事务A修改的数据事务B读取不到;但是当事务A提交完事务之后,事务B再一次的快照读,此时会重新生产Read View,此时事务A不再是活跃的事务了,此时事务B则读得到事务A提交的数据。

RR(可重复读)
可重复读可以解决脏读、不可重复读。
我们来看下面两个事务:

事务A 事务B
开启事务 开启事务
快照读,a=500 快照读,a=500
更新为a=400
提交事务
快照读,a=500

我们可以发现,事务B第一次的快照读a=500,然后等待事务A提交后,再一次的快照读a还是为500,这保证了事务B的重复读取的数据是一样的,这是为什么呢?

上篇文章我们说到,事务的一次快照读都会伴随的创建与其对应的一个Read View。
当事务B第一次进行快照读的时候,此时建立了Read View,由于事务A属于正在活跃的事务,所以事务A的修改对事务B来说是不可见的(详细可以看上一篇文章)。当事务A提交事务时,事务B再一次的快照读,此时不会再去新建Read View,而是沿用了事务B的第一次快照读所创建的那个Read View,所以很明显此时读出来的a还是500。

所以总是来说,导致RC、RR这两种隔离级别的快照读不同愿意就是,RC级别下,每一次的快照读都会重新生产Read View,而RR级别下,则会沿用第一次快照读生成的Read View。