MySQL可重复读隔离级别并没有完全解决幻读

MVCC产生幻读的场景

两种读法解决幻读的方法

  • 快照读:使用快照Read View,插入的数据,他的事务号也是插入任务所属的那个事务,只需要照常检查这个事务是否是可见的即可

  • 当前读:select···for update这种查询是当前读,因为每次读取都是为了拿来在其基础上修改,为了防止修改丢失这种情况,需要确保每次拿到的都是最新的数据,而幻读正是出现在这里的

    • 想要解决幻读,一个方法就是加锁,不让其他事务进行插入,这是串行化隔离级别的方法

    • 想要在可重复读隔离级别下处理当前读的幻读问题,使用的是间隙锁

 

间隙锁是什么呢,执行了当前读任务之后,比如读取行的id是>2,就对这个范围的数据加上next-key lock(间隙锁和记录锁的组合),然后当其他事务执行插入的时候,会生成一个插入意向锁,同时进入等待状态,直到最开始的事务进行了commit,这样就避免了幻读

两种未被解决,发生幻读的场景

  • 第一种:MVCC的漏洞

    • A第一次执行了select生成了Read View,之后事务B进行了插入,这时候A如果想要再次查找,拿到的版本号是在快照之后生成的,是不可见的

    • 随后A对这个数据进行了update,版本号变为A的事务id了,突然又可以查到了

  • 第二种

    • 第二种比较简单,就是第一次读是快照读,第二次是当前读,第二次读并没有依赖第一次查到的快照,第一次也没有给第二次读创造锁

    • 所以不能读到

posted @ 2022-11-06 21:51  木马伊人  阅读(244)  评论(0)    收藏  举报