事务的隔离状况

事务的隔离级别

    可重复读:查询只承认在事务启动之前已经提交的数据

    读提交:查询只承认在语句启动前已经提交的数据

    当前读:总是读取已经提交完成的最新版本

在Mysql中有两个视图的概念:

    1、一个是view,一个用查询语句定义的虚拟表,在调用的时候执行查询语句并返回结果

    2、另外是InnoDB为了实现MVCC时用到的一致性视图,用于支持RC-读提交、RR-可重复读隔离级别的实现

快照在MVCC的工作方式简述:

    可重复读隔离级别,事务在启动的时候基于整个库“拍”了个快照;实际上他的快照操作并不是对数据的复制,不然就不会快速的启动一个事务,实际上是基于事务的ID来实现的

    事务启动会向InnoDB事务系统申请一个事务ID,每一行数据都会有多个版本,即数据的每次更新都会向系统申请一个新的事务ID(事务ID的生成方式上一篇《自增id用完怎么处理》说过);旧的版本要保留且可以通过新的版本中的数据(undo log)拿到,在实现上InnoDB为每个事务构造了一个数组,用来保存事务启动瞬间还“活跃”的所有事务ID,活跃指启动还没有提交。数组中事务ID最小的为“低水位”,最大的事务ID+1为高水位,这个视图数组和高水位组成了一致性视图(read-view);数据的可见行规则就是根据这个视图对比得到的结果。

    视图数组把所有row trx_id分为:已提交事务、未提交事务集合(当前事务)、未开始事务;

    一个数据版本的row trx_id落在已提交集合则数据是可见的,落在未开始集合数据不可见,落在为提交事务集合则分为两种情况(落在集合并不一定表示一定在集合只能说明比高水位的row trx_id小):在数组中表示该版本由还未提交的事务生成 不可见,不在集合中表示由已提交的事务生成 可见(这里其实搞的不是很明白,,,记录下来)。所以InnoDB利用所有数据多版本的特性,秒级创建了快照

这种说法更浅显一点:一个数据版本,对于数据视图来说除了自己的更新可见以外有以下三种情况:

    1、版本未提交 不可见

    2、版本已提交,在视图数组创建之后提交 不可见

    3、版本已提交,在视图数组创建之前提交 可见

注:更新数据时有一条逻辑--更新数据时总是先读后写,而这个读指的是 当前读;必须要读取最新版本的数据,且必须加锁

其实这就和可重复读隔离级别就有点相悖了;那事务的可重复读的隔离级别是怎么实现的?

    即:可重复读的核心是一致性读,事务在更新数据时只能用当前读,如果当前记录的行锁被其他事务占用,那就需要进入所等待

另--读提交和可重复读的区别:

    1、可重复读隔离级别下,只需要事务开始时创建一致性视图,后续事务里的其他查询操作都共用这一个视图

    2、读提交隔离级别下,每次执行语句前都会创建一个新的视图

小小结:

    开始也做了一个小结,这里提一个小点:表结构不支持“可重复读”的原因是,表结构没有对应的行数据,也没有row trx_id 所以只有遵循当前读的逻辑

参考林晓斌《Mysql45讲》 

    

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值