幻读及MVCC间隙锁
zhaolengquan Lv3

什么是MVCC

如果读取的行正在执行DELETE或UPDATE,这时读取操作不会因此去等待行上锁的释放,相反的innodb存储引擎会读取行的一个快照数据。

当前读和快照读

当前读:读取的是最新的数据,而不是历史数据

当前读是基于next-key lock(行锁+间隙锁)来实现的,使用insert,update,delete,select···for update,select···lock in share mode语句 以及加锁的select语句。

快照读:读取的是快照数据,快照读是基于MVCC和undolog实现的,使用于简单的非阻塞的select语句,

RR级别下:当前读是通过手动加record lock(行锁)和gap lock(间隙锁)来实现的。

快照读在RR和RC隔离级别下的区别

RC(Read Commited读已提交)

在RC隔离级别下读取的是最新的数据

事务中的每个Sql都会生成一个readView,一个事务内的多条SQL语句会生成多个readView,而每条sql执行的时候,都是查询最新的readView的值。

比如说事务A有两次查询语句,在第一个查询 sql 生成一个 readView(事务视图 id = n),事务 B 对该数据做了操作,那么就会生成新的 readView(事务视图 id = n + 1),第二个查询 sql 语句获取该条数据时,就会去 readView(事务视图 id = n + 1)查询数据。

RR:事务开始的时候生成一个readView,所以一个事务内的多条查询sql,查询同一条数据时,读取到的readView都是同一个,那么查询某条数据的值也是同一个值。

解决幻读

在RR隔离级别下,MVCC下innodb解决了不可重复度和快照读情况下的幻读。当前读情况下的幻读问题需要靠next-key锁

innodb对于当前读 行的查询采用next key锁,锁的不是单个值,而是一个范围(GAP)

 Comments