Mysql的Innodb的RR隔离级别到底有没有解决幻读问题?

InnoDB中的repeatable read这种隔离级别通过间隙锁+MVCC解决了大部分的幻读问题,但是并不是所有的幻读都能解读,想要彻底解决幻读,需要使用Serializable的隔离级别。

MVCC解决幻读

在RC中,每次读取都会重新生成一个快照,总是读取行的最新版本。在RR中,快照会在事务中第一次SELECT语句执行时生成,只有在本事务中对数据进行更改才会更新快照。

有下面执行过程:

由于RR下一个事务中只会生成一个readview,所以事务1第二次select时并没有查询到事务2插入进来的数据。解决了幻读。

间隙锁解决幻读

加锁的select或update后会更新当前快照:

select * from table lock in share mode;
select * form table for update
insert into table ...
update table ...

这个例子中,事务1select时用了间隙锁锁上了10到30之间的数据,所以事务2插入时会被阻塞,直到事务1commit或rollback后。

没有完全解决幻读

如果第一个例子中是加锁的select,那么则会查到事务2提交的数据,即发生了幻读。或者下面的例子也是:

事务2插入后,事务1两次select,第二次select到了事务2新插入的数据,即又发生了幻读!

或者再下面这个例子,也是发生了幻读:

在RR中,如果本事务中,执行了加锁的select或更新数据后,都会更新快照。

怎么避免幻读

如果想要彻底解决幻读的问题,在InnoDB中只能使用Serializablei串行执行这种隔离级别。但是,实际场景中,几乎很少连幻读都接受不了的场景,甚至不少大厂为了并发度都把RR改成RC。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值