Mysql怎么解决幻读问题(innoDB)
幻读:在一个事务中,第一次读取的行数和第二次读取的行数不一致。可以见到别的事务新插入的行,并且得是已提交的事务
在隔离级别定义中,可重复读级别下是解决不了幻读的。所有innoDB引入了锁机制解决。
要知道可重复读级别的实现是MVCC。
对于快照读,也就是处于事务中的读来说。只能见到开启事务的一刻数据库的数据状态。另外一个事务新插入的行也是不可见的。
实验DEMO,5.7版本的
快照读下,部分解决幻读问题
数据和索引,id为主键索引
事务A第一次快照读下查询数据为6条,注意begin;只有在运行了第一条sql之后才会开启事务。不是说一执行begin就开启
事务B插入一行之后查询行数为7
事务A快照读下依旧为6
结论:快照读下可以部分解决幻读问题。但是如果在事务A中执行update语句涉及到了新插入的行。
在事务A中执行上图语句,会涉及到新插入的4,4,4一行。此时事务A再次查询行数,如下图已经变成了7条。所以说是部分解决。
当前读依靠行锁解决
实验DEMO
依靠行锁解决:在当前读下会对行加锁,其它事务就不能新插入行,只有当前事务锁释放后才可插入。
加行锁的基本单位是next-key lock 临键锁 锁的范围是 左开右闭
sql:
select * from t where id = 5 for update;
加锁范围: (0,5] 等值唯一查询 加锁退化为行锁,只锁5
selec * from t for update;
锁住全表
(0,5],(5,10],(10,15],(15,20],(20,25],(25,+无穷],
注意得是可重复读级别下。
事务A当前读
事务B插入