InnoDB存储引擎+[可重复读]事务隔离级别即可避免幻读的发生,不需[串行化]
前言
遥想2019年,准备校招面试过程中背"八股文",背了这样一个知识点:数据库事务隔离级别有 读未提交、读已提交、可重复读、串行化。其中,读已提交能解决脏读问题;可重复读能解决脏读、不可重复读问题;串行化能解决脏读、不可重复读、幻读问题。
这个知识点一直记在了脑海里,没有去更深入地理解。
近日在学习过程中,发现在InnoDB存储引擎下,【可重复读】事务隔离级别也可以避免幻读的发生,故此记录。
拨开云雾
以下内容摘自《MySQL技术内幕:InnoDB存储引擎》p269
幻读问题是指在同一事务下,连续执行两次同样的SQL语句可能导致不同的结果,第二次的SQL语句可能会返回之前不存在的行。下面将演示该例子,表t由1、2、5这三个值组成,若这时事务T1执行如下的SQL语句:select * from t where a > 2 for update; 注意这时事务T1并没有进行提交操作,上述应该返回5这个结果。若与此同时另一个事务T2插入了4这个值,并且数据库允许该操作,那么事务T1再次执行上述SQL语句会得到结果4和5。这与第一次得到的结果不同,违反了事务的隔离性,即当前事务能够看到其他事务的结果。
InnoDB存储引擎采用Next-Key Locking算法避免幻读问题。对于上述的SQL语句,其锁住的不是5这单个值,而是对(2,正无穷大)这个范围加了X锁。因此任何对于这个范围的插入都是不被允许的,从而避免幻读。
2021-12-21更正:MySQL InnoDB存储引擎的 REPEATABLE-READ(可重复读)并不保证避免幻读,需要应用使用加锁读来保证。而这个加锁度使用到的机制就是 Next-Key Locks。
行锁的3种算法
Record Lock:单个行记录上的锁
Gap Lock:间隙锁,锁定一个范围,但不包含记录本身
Next-Key Lock:Gap Lock+Record Lock,锁定一个范围,且锁定记录本身
Record Lock总是会去锁住索引记录,如果InnoDB存储引擎表在建立的时候没有设置任何一个索引,那么这时InnoDB存储引擎会使用隐式的主键来进行锁定。
Next-Key Lock是结合了Gap Lock和Record Lock的一种锁定算法,在Next-Key Lock算法下,InnoDB对于行的查询都是采用这种锁定算法。
采用Next-Key Lock的锁定技术称为Next-Key Locking。其设计的目的是为了解决虚读/幻读问题,锁定的是一个范围。
技术还是要加以实践啊,之前校招为了找工作,背了很多知识点,但没有真正吃透。想要真正掌握知识,还是需要有自己理解的。

浙公网安备 33010602011771号