MySQL的RR隔离级和间隙锁

select * from t where d=5 for update;使用的是当前读;当前读的规则就是能够读到所有已经提交的记录的最新值;

幻读 仅仅指新插入的行;

如何解决幻读

    产生幻读的原因是,行锁只能锁住已经存在的行,但是对于向行之间insert数据行这个动作,要更新的是记录之间的间隙。为解决这个问题,InnoDB引入了 gap lock。间隙锁就是锁住两个值之间的间隙。上述插入6条记录机会形成7个间隙。

    当有间隙锁的时候,select * from t for update;不仅给数据库上的6条记录加行锁,同时加7个间隙锁。这样可以确保没有数据可以插入。

    行锁分为读锁和写锁,其中写锁是互斥的;间隙锁只和向间隙中插入数据有冲突,多个会话之间的间隙锁是不冲突的。

    间隙锁和行锁合称为next-key lock,每个next-key lock都是前开后闭的区间。也就是说select * from t for update;会形成7个next-key lock,分别是:(-∞,0]、(0,5]、(5,10]、(10,15]、(15,20]、(20, 25]、(25, +supremum]。

间隙锁可能会带来死锁的问题

MySQL的RR隔离级和间隙锁_第1张图片

间隙锁的引入可能会影响并发访问。

对于select * from t where id=9,这样一个不存在行,锁住的区间是(5,10);

对于select * from t where id=5,这样存在的行锁住的是(0,5]这样的区间,其实也就是一个行锁加一个间隙锁,就构成了一把net-key lock;

间隙锁只有在RR隔离级下才可以生效,在RC隔离级下无法生效的。

你可能感兴趣的:(mysql技术)