MVCC
Multi-Version Concurrency Control 多版本并发控制,MVCC 是一种并发控制的方法,一般在数据库管理系统中,实现对数据库的并发访问;在编程语言中实现事务内存。
实现方式
MVCC多版本并发控制指的是 “维持一个数据的多个版本,使得读写操作没有冲突” 这么一个概念。具体的实现方式为:
版本链 + Undo回滚日志 + readView
数据库中的表在进行存储的时候为了实现版本链,会为每条记录生成两个隐藏字段,分别为Transaction ID 以及 Roll Point, 数据库的读操作为快照读(ReadView),写操作为当前读(最新版本)。不同的隔离级别RR 和 RC,ReadView 生成的时机不同, 具体来讲,RR由于需要解决不可重复读问题,只在第一次Select(读)的时候进行ReadView的生成,而RC在每次Select都会生成新的ReadView。
那么问题来了?怎么根据ReadView去读取我们需要的数据?
- 已提交事务ID < min TransactionID
- min TransactionID<= 未提交与已提交事务 <= max TransactionID
- 未开始的事务 > max TransactionID
每次的ReadVIew 我们需要根据TransactionID 判断当前事务是否已经Commit,否则就根据RollPoint 去Undo log进行寻找 Commit的id,这个过程需要ReadView进行判断是否已经提交。
幻读为什么产生?
当前读和快照读不一致
怎么解决幻读
即使给每行数据都加上行锁,也无法解决幻读,行锁只能阻止修改,无法阻止数据的删除。而且新插入的数据,自然是数据库中不存在的数据,原本不存在的数据自然无法对其加锁,因此仅仅使用行锁是无法阻止别的事务插入数据的。
为了解决幻读问题,InnoDB 只好引入新的锁,也就是间隙锁(Gap Lock)。顾名思义,间隙锁,锁的就是两个值之间的空隙。锁起来不让其他事务修改当前读和快照读一致就不会出现幻读啦