MySQL学习笔记 - 7 - 事务隔离级别与MVCC

事务隔离级别

读未提交

一个事务还没提交的时候,它做的变更能够被其它事务看到

读提交

一个事务提交之后,她做的变更才会被其它事务看到

可重复读(默认)

一个事务在执行过程中看到的数据,跟这个事务在启动的时候看到的数据是一致的(一致性读)

串行化

对于同一行记录的操作,会对应家伙是那个读锁写锁,当读写冲突的时候,事务会串行执行

实际上每一种事务隔离级别都会解决一种问题,但同时也会引申出另一种问题

  • 读未提交的隔离级别会产生脏读问题
  • 读提交的隔离级别解决脏读问题,但是同时产生不可重复读的问题
  • 可重复读的隔离级别解决了不可重复读的问题,但同时产生幻读问题
  • 串行化的隔离级别解决了幻读问题

在事务隔离级别为可重复读下出现的幻读问题是指,根据某次select结构执行insert操作,在事务提交的时候,发现insert操作执行失败(引发主键冲突),就像在事务提交的一刻,表中出现了幽灵行,占用了事务想要执行insert操作的位置,所以幻读专指的是在可重复读级别下的insert操作出现幽灵行的问题,并不是在事务执行过程中,出现先后两次read的结果不一致!!

事务启动方式

begin/start transaction,配套commit

    
    begin;
    
    ....
    
    commit;
    
复制代码

begin/start命令并不是一个事务的起点,在执行begin/start之后的第一个操作InnoDB表的语句才是事务正真启动的时间点

如果想要马上启动一个事务,可以使用start transaction with consistent snapshot命令

参数设置

    set autocommit = 1;
复制代码

MVCC(多版本并发控制)

MVCC可以让InnoDB事务在某些事务隔离级别下实现一致性读的功能

一致性读

根据时间点通过快照信息显示查询结果,无需关心此时是否有其他事务在执行

  • 通过undo log将数据回滚至历史某个版本,从而实现秒级创建数据库快照的特点
  • 可重复读事务隔离级别下,事务第一个读操作的时候,生成快照信息(一致性读视图)
  • 读提交事务隔离级别下,事务中的每个读操作,都会重置快照信息(将当前快照更新为最新的数据视图)

可重复读级别下的MVCC实现

三点前提

  • 每个事务在启动的时候,InnoDB会给事务分配一个事务ID(自增,唯一,类似主键)

  • InnoDB表的行记录存在两个隐藏行,事务ID列(row trx_id)和回滚指针列row trx_id代表的实际上是数据的版本,在提交事务的时候,row trx_id列会被赋值为提交的事务的事务ID

  • 事务在启动的时候,同时会设置事务的up_limit_idup_limit_id是用来表明,事务在执行过程中,能看到的数据版本的上限(也就是说,select某一行数据,判断事务应该看到那个版本的数据,应该根据当前行的row trx_id <= up_limit_id

那么基于以上三点,可重复读级别下的MVCC的执行流程应该如下图

事务A和事务B分别将id = 1的这一行更新为v = 2v = 3

那么在id = 1的这行数据的当前row trx_id(数据版本)等于4

此时,有一个事务C对id = 1的这行执行读操作,事务C的up_limit_id = 3,那么该事务读到的数据版本就应该是row trx_id = 2, v = 2

事务C查询id = 1的那一行数据的时候,发现数据的版本row trx_id = 4 > 事务C的up_limit_id = 3

然后通过undo log回滚到上一版本v = 2, row trx_id = 2,此时再次比较,发现数据的版本row trx_id = 2 《 事务C的up_limit_id = 3,表示数据可见!!

MVCC的数据快照实际上是通过当前的数据版本再加上回滚段,来实现这种轻量级的保存数据快照的方式

可重复读隔离级别下,长事务的危害

在长事务的执行过程中,随着其他事务的提交,数据的row trx_id会不停增加,此时row trx_id与长事务的up_limit_id的差距会越来越大,这意味着,系统保留的undo log的回滚段会越来越大

那么长事务中执行一条select语句的时候,InnoDB会根据当前版本的数据 + 大量的undo log的回滚段得出该事务的一致性读视图,undo log占用大量的存储空间,同时select语句的 执行时间也会边长

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值