前言
这篇文章介绍MySQL里面InnoDB引擎事务的多版本并发控制机制(MVCC),可以用来实现两种事务的隔离级别:read committed和repeatable read(关于事务隔离级别的介绍,可以参考这篇文章:https://blog.csdn.net/qq_33290787/article/details/51924963)。同时MVCC解决了repeatable read中可能出现的幻读的问题。
实现
MVCC的核心就是给每行数据增加了两个隐藏的列,一个是修改这行的最后的系统版本号(system version number),一个是删除该行的系统版本号。每开始一个新事物,系统版本号就会递增。事务开始的时候,系统版本号会作为当前事务的版本号,用来查询和操作。
SELECT:
a. InnoDB只会读取版本号小于等于该事务版本号的所有数据行,这样保证了事务进行时,所有的行要么是事务进行前已经存在,要么是事务自身插入或者修改的(这样实现了事务重复读取数据一致,同时不会出现幻读的现象)
b. 同时读取的行的删除版本号要么是未设置的,要么大于当前事务版本号,这样保证该行在事务开始前没有被删除。
INSERT:
InnoDB为新插入的每一行保存当前的系统版本号作为行版本号。
DELETE:
InnoDB为删除的每一行保存当前系统版本号作为删除版本号。
UPDATE:
InnoDB将更新数据插入新一行,将事务版本号作为新一行的行版本号,同时将老一行的删除版本号置为当前事务版本号。
优缺点
优点:1. 在事务中,大多数的读操作不需要加锁 2. 解决了repeatable read中幻读的问题
缺点:1. 每行记录都需要额外的存储空间 2. 需要更多的行检查和维护工作
一点感想
数据版本号在我们日常工作中很多地方都可以发挥作用:例如实现幂等、简单的乐观锁机制等等。希望之后能够多学习多实践,有朝一日能够比较完善地总结一下数据版本号的各种用途。