结论:mysql在RR隔离级别下绝大部分场景解决了幻读
MySQL如何解决幻读:
1、非锁定读(普通的select) 通过 readView 解决幻读
2、锁定读(select for update)通过锁解决幻读
没有解决的场景:
1、场景1
事务1 | 事务2 |
---|---|
begin | |
select * from user where id > 3 | begin |
insert into user(id, name) values (5,‘zhangsan’) | |
commit | |
update user set name =‘lisi’ where id = 5 | |
select * from user where id > 3;//可以看到id = 5的数据 |
为什么可以看到?这个可以了解下readView的结构及工作原理
2、场景2
事务1 | 事务2 |
---|---|
begin | |
select * from user where id > 3 | begin |
insert into user(id, name) values (5,‘zhangsan’) | |
commit | |
select * from user where id > 3 for update;//可以看到id=5的数据 |
这个场景属于当前读与快照读不一致。这种不一致算不算幻读有争论,暂时没找到比较权威的结论。
对于幻读实际开发中没必要过于害怕,从而无脑的选择RR。《mysql运维内参》推荐互联网应用默认使用RC隔离级别,一方面是RR导致死锁的情况比较多,另一方面我们实际业务其实是可以接收幻读的。