美文网首页
MySQL 事务

MySQL 事务

作者: 侧耳倾听y | 来源:发表于2021-09-09 00:13 被阅读0次

    隔离性

    隔离级别
    1. 读未提交(read uncommitted);
      一个事务还未提交时,它的变更就能被别的事务看到。(脏读问题)
    2. 读提交(read committed);
      一个事务提交之后,它做的变更才会被其他事务看到。(不可重复读、幻读问题)
    3. 可重复读(repeatable read);
      一个事务执行过程中看到的数据,总是跟这个事务在启动时看到的数据是一致的。
    4. 串行化(serializable)。
      对于同一行记录,写会加写锁,读会加读锁。当出现读写锁冲突的时候,后访问的事务必须等前一个事务执行完成,才能继续执行。

    不同隔离级别,在一些场景看到的查询结果是不同的,在实现上,是通过创建一个视图,访问的时候以这个视图为准:

    1. 可重复读,这个视图是在事务启动时创建的,整个事务存在期间都用这个视图;
    2. 读提交,这个视图是在每个SQL语句开始执行的时候创建的;
    3. 读未提交,直接返回记录上最新的值;
    4. 串行化,加锁避免并行访问。
    MVCC
    • read view
      实现mvcc用到的一致性视图,即 consistent read view,用于支持RC和RR隔离级别的实现。

    RC级别下,每一个SQL语句创建一个read view;RR隔离级别下,在事务一开始创建一个read view并一直使用。

    • 事务id
      InnoDB每个事务都有一个唯一的事务id,叫做transaction id,是在事务开始时向事务系统申请的,按照申请顺序严格递增。

    每行数据都有一个隐藏字段row_trx_id,这个字段的值就是transaction id。

    • undo log
      每条记录在更新的的同时会记录一条回滚操作(undo log),记录上最新的值,可以通过回滚操作,得到前一个状态的值。同一条记录在系统可以存在多个版本,这就是数据库的多版本并发控制(MVCC)。

    回滚日志会在不需要的时候删除:系统里面没有比这个回滚日志更早的read-view的时候。

    • 可重复读实现
    1. 事务数组:InnoDB为每个事务构造了一个数组,用来保存这个事务启动的时候,当前正在活跃(启动但还未提交)的所有事务id;
    2. 低水位:数组里面事务id的最小值;
    3. 高水位:当前系统里面已经创建过的事务id最大值+1;
    4. 一致性视图:由事务数组和高水位组成。

    数据版本的可见性,基于数据的row_trx_id和一致性视图对比的结果。对于当前事务启动瞬间来说,一个数据版本的row_trx_id可能有几种情况:

    1. 绿色部分:这个版本是已提交的事务或者当前事务自己生成的,这个数据是可见的;
    2. 红色部分:这个版本的数据是由将来启动的事务生成的,是不可见的;
    3. 黄色部分:a.如果如果row_trx_id在数组中,表示这个版本是由还没提交的事务生成的,不可见;b.如果row_trx_id不在数组中,表示这个版本是已经提交了的事务生成的,可见。



      总结来说:

    4. 版本未提交,不可见;
    5. 版本已提交,但是实在视图创建后提交的,不可见;
    6. 版本已提交,而且实是在视图创建前提交的,可见。
    • 一致性读和当前读
    1. 一致性读:普通查询都是一致性读,具有可重读的特点;
    2. 当前读:更新数据都是先读后写的,而这个读,只能读当前的值,称为“当前读”。

    相关文章

      网友评论

          本文标题:MySQL 事务

          本文链接:https://www.haomeiwen.com/subject/qjcmwltx.html