为什么事务的隔离级别设置为可重复读
时,不管其他事务有没有变更过数据,当前事务都可以读到相同的数据记录呢?这就是Mysql的MVCC机制,在读已提交
的事务隔离级别下也有用到MVCC机制。MVCC全称Multi-Version Concurrency Control
比如下面这个演示:
前置概念介绍
undo日志
undo日志是指某条数据发生变更时,操作它的事务会在事务提交前将变更前数据保存到undo日志中,并使用trx_id
和roll_pointer
两个隐藏字段将undo日志串联起来,形成一个版本链。
一致性视图(read-view
)
在可重复读的隔离级别下,开始事务时,执行任意查询语句(不需要是当前表)时会生成当前事务的一致性视图,该视图在事务提交前是不会变化的(在读已提交
的事务隔离级别下,每次执行查询语句都会重新生成)
- 视图组成
所有未提交事务的trx_id
数组+已创建的最大事务的trx_id
,其中trx_id
在事务执行变更操作时才真正生成。
MVCC
版本比对规则
根据生成的一致性视图从版本链(undo日志)中查找可见数据。
若一致性视图如下图例所示为[20,30],30。
根据一致性视图将事务id划分为三个区间: (0,20), [20,30], (30, +∞)
第二区间划分说明: 20为数组中最小的事务id,30为服务端已创建的最大事务id。
可见规则如下:
- 若版本链中的
trx_id
处于第一区间,则认为是可见的。 - 若版本链中的
trx_id
处于第三区间,则认为是不可见的。 - 若版本链中的
trx_id
处于第二区间,判断是否处于数组中,如果处于数组中且当前事务id不等于trx_id
则认为不可见,反之可见。
图示说明