上图是一个演示RR隔离级别下MVCC的例子,基于这个例子有点扩展性的问题琢磨不清,特来球教一下大家:
就是图中事务5中的查找是基于id的,如果改成依照age=3来查找,会是什么情形?
当然第一次查询是能找到id=30的这条数据的,按照理想状况,第二次查询应该也能。
但是按照目前我对该机制的理解,逐个回溯历史版本的第一步是在数据库(当前最新状态)中找到对应的数据吧,此时id=30的这条数据已经被事务4改成age=10了,那查询的第一步就找不到这条数据了吧。同时也不会直接去undo log里找对应的历史数据吧,不沿着数据版本链找等于大海捞针。
那岂不是就会出现一个很反直觉的情形?——明明是RR隔离级别下的两次快照读,中间也没穿插当前读,用的ReadView都是同一个。但读到的数据已经不一样了,是不是属于直接违反可重复读的定义了?
然后我又想到一种可能,这种情形是不是属于幻读?但是就我之前学到的理论里,幻读包括的情形有“读取时不存在但试图插入数据时却提示数据已存在而插入失败”或者“查询时存在但试图删除或修改时却提示不存在”,都在试图进行DML操作时才暴露问题,但上面例子里明明是两个单纯的查询,特征上也不符合。是我用的教程太过狭隘么?还是刚刚的推断中有所偏差(压根不是幻读)?还是有啥我没有掌握或理解偏差的基础知识?实在有些迷惑,求各位指点一二,谢谢大家。