问题
前段时间一直有一个问题困扰着我,在可重复读的隔离级别下,到底有没有解决幻读的问题?
思考
什么是幻读
幻读是指我当前事务在查询的时候,另一个事务进行了insert操作后,第一次查询和第二次查询的结果不一致,因为第二次查询查到了另一个事务操作后的数据。
注:delete和update不属于幻读
mysql解决幻读
mvcc
通过mvcc,mysql在RR的隔离级别下,如果另一个事务进行了insert操作后,第二次查询到的结果依旧和第一次保持一致,因此不会发生幻读。
间隙锁
在当前读情况下,对数据进行了加锁操作,这个时候另一个事务的insert操作会被阻塞,因此也不会发生幻读。
但是真的完全解决了幻读吗?
看下面的两个例子:
快照读事务进行了当前读
- case1: 即事务在进行第二次查询的时候使用了当前读,当前读会读到最新的数据
select for update
- case2: 事务在另一个事务进行insert操作后进行了update操作,由于update操作也是当前读,因此也会存在幻读
结论
mysql RR隔离基本下的幻读,并没有得到完全的解决,如果需要完全避免幻读则需要使用序列化的隔离级别。同时在RR隔离级别下进行update的时候为了避免最后更新的数据不一致,需要增加乐观锁。