MVCC产生幻读的场景
两种读法解决幻读的方法
-
快照读:使用快照Read View,插入的数据,他的事务号也是插入任务所属的那个事务,只需要照常检查这个事务是否是可见的即可
-
当前读:select···for update这种查询是当前读,因为每次读取都是为了拿来在其基础上修改,为了防止修改丢失这种情况,需要确保每次拿到的都是最新的数据,而幻读正是出现在这里的
-
想要解决幻读,一个方法就是加锁,不让其他事务进行插入,这是串行化隔离级别的方法
-
想要在可重复读隔离级别下处理当前读的幻读问题,使用的是间隙锁
-
间隙锁是什么呢,执行了当前读任务之后,比如读取行的id是>2,就对这个范围的数据加上next-key lock(间隙锁和记录锁的组合),然后当其他事务执行插入的时候,会生成一个插入意向锁,同时进入等待状态,直到最开始的事务进行了commit,这样就避免了幻读
两种未被解决,发生幻读的场景
-
第一种:MVCC的漏洞
-
A第一次执行了select生成了Read View,之后事务B进行了插入,这时候A如果想要再次查找,拿到的版本号是在快照之后生成的,是不可见的
-
随后A对这个数据进行了update,版本号变为A的事务id了,突然又可以查到了
-
第二种
-
第二种比较简单,就是第一次读是快照读,第二次是当前读,第二次读并没有依赖第一次查到的快照,第一次也没有给第二次读创造锁
-
所以不能读到
-