在上一篇文章我向大家介绍了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。
近期评论