Mysql锁

75 阅读2分钟

READ COMMITTD在每一次进行普通SELECT操作前都会生成一个ReadView,而REPEATABLE READ只在第一次进行普通SELECT操作前生成一个ReadView,之后的查询操作都重复使用这个ReadView就好了。

MySQL 是怎么解决幻读的?

MySQL InnoDB 引擎的默认隔离级别虽然是「可重复读」,但是它很大程度上避免幻读现象(并不是完全解决了,详见这篇文章 (opens new window)),解决的方案有两种:

  • 针对快照读(普通 select 语句),是通过 MVCC 方式解决了幻读,因为可重复读隔离级别下,事务执行过程中看到的数据,一直跟这个事务启动时看到的数据是一致的,即使中途有其他事务插入了一条数据,是查询不出来这条数据的,所以就很好了避免幻读问题。
  • 针对当前读(select ... for update 等语句),是通过 next-key lock(记录锁+间隙锁)方式解决了幻读,因为当执行 select ... for update 语句的时候,会加上 next-key lock,如果有其他事务在 next-key lock 锁范围内插入了一条记录,那么这个插入语句就会被阻塞,无法成功插入,所以就很好了避免幻读问题。

唯一索引与非唯一索引加锁

【对于当前读,等值匹配条件数据存在时】

唯一索引会将「临建锁 」会退化成「记录锁」 非唯一索引「临建锁 」不会退化,并且还会加上往后第一个不匹条件的数据所在「间隙锁」 · 【对于当前读,等值匹配条件数据不存在时】

唯一索引和非唯一索引「临建锁 」都会退化成「间隙锁」 · 【对于当前读,条件范围匹配】

锁的范围是条件范围所在的「临建锁」并集,并止于往后第一个不匹配范围的数据所在临建锁 唯一索引的起始范围可能会退化成记录锁,非唯一索引的起始范围不会退化成记录锁