MySQL是如何实现事务隔离级别的——详解MVCC原理

事务的四个隔离级别,读未提交、读已提交、可重复读和串行化,先来说说读未提交和串行化的实现方式:

  • 读未提交:在并发事务访问时,事务可以看到其他事务未提交的数据,也就是不采取任何措施,就实现了读未提交的效果。
  • 串行化:读的时候加共享锁,其他事务可以并发读,但是不能写。写的时候加排它锁,其他事务不能并发写也不能并发读。

所以只有读已提交和可重复读是通过MVCC实现的,MVCC(Multi-Version Concurrency Control)是多版本并发控制的缩写,对于每个数据行,都会维持多个版本。

MVCC有两个重要知识点:

  • 版本链:数据库中的每行数据包含隐藏字段事务id(trx_id)和回滚指针(roll_pointer),事务id记录修改该数据的事务id,回滚指针记录上一版本地址(在undo log中记录)。多个事务并行操作某一行数据时,不同事务对该行数据的修改会产生多个版本,然后通过回滚指针(roll_pointer),连成一个链表,这个链表就称为版本链,通过版本链,我们可以访问到前面版本的数据。

  • Read View:Read View是事务执行SQL语句时产生的读视图。Read View会记录创建该Read View的事务id(creator_trx_id),当前活跃的事务(即未提交的事务)列表(m_ids),该列表包含创建该Read View的事务id,活跃事务中最小的事务id(min_limit_id),系统中应该分配给下一个事务的id(max_limit_id),即全局最大的事务id+1。

根据Read View,就可以判断数据的哪些版本是可读的,具体如下:

  • 数据行事务id < Read View中活跃事务最小id:表明该数据是已提交的事务改动的,是可见的。
  • Read View中活跃事务最小id <= 数据行事务id < Read View中准备分配给下一个事务的id:如果数据行事务id等于创建该Read View的事务id,说明该数据是当前事务自己修改的,是可见的。如果活跃列表中包含数据行事务id,说明是未提交事务修改的数据,不可见。如果活跃列表中不包含数据行事务id,说明是已经提交的事务修改的数据,可见。
  • 数据行事务id >= Read View中准备分配给下一个事务的id:说明是未来的事务修改的数据,不可见。

对于不可见的数据版本,可以通过版本链找到之前的版本,如果之前的也不可见,就继续往前找,直到找到可见的数据版本。

MVCC实现可重复读:事务开启后第一次执行select时生成Read View。可重复读的含义同一事务内多次读取同一数据,数据不能发生变化,比如事务1读数据,事务2修改数据,事务1再次读取数据,数据不能发生变化。那么在MVCC下,事务1第一次读时生成的Read View中记录了活跃的事务2(事务2后续还要修改数据,所以肯定未提交,是活跃的),第二次读取时发现当前数据版本被活跃事务修改,是不可见的,就会向前寻找未被事务2修改的可见的数据版本,保证了数据的可重复读。

MVCC实现读已提交:事务中每次执行select时都生成Read View。读已提交的含义是事务只能读取已经提交的事务修改的数据。在MVCC中,事务每次读取数据时都生成一个新的Read View,更新活跃事务列表,已提交的数据的事务id不在活跃列表中了,那么数据自然是可见的。

MVCC解决幻读问题:可重复读隔离级别下,只会在事务开启后的第一次查询时生成Read View,并使用这个Read View直到事务提交。所以在生成 Read View之后其它事务所做的更新、插入记录版本对当前事务并不可见,防止了“幻读”。

此外,MySQL还可以使用临键锁Next-key-Lock 防止幻读。执行 select...for update/lock in share mode、insert、update、delete 等当前读时,会锁定读取到的记录和它们的间隙,防止其它事务在查询范围内插入数据,不能插入自然就不会幻读。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值