MySQL 事务

2021-09-09  本文已影响0人  侧耳倾听y

隔离性

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

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

  1. 可重复读,这个视图是在事务启动时创建的,整个事务存在期间都用这个视图;
  2. 读提交,这个视图是在每个SQL语句开始执行的时候创建的;
  3. 读未提交,直接返回记录上最新的值;
  4. 串行化,加锁避免并行访问。
MVCC

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

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

回滚日志会在不需要的时候删除:系统里面没有比这个回滚日志更早的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. 当前读:更新数据都是先读后写的,而这个读,只能读当前的值,称为“当前读”。
上一篇下一篇

猜你喜欢

热点阅读