MySQL 事务详解

MySQL 事务详解

1. 什么是事务

事务是指数据库中一系列操作,得全部都完成,然后才能提交事务,对于已经提交的事务来说,该事务对数据库所做的修改将永久生效,如果中途发生发生中断或错误,那么该事务期间对数据库所做的修改将会被回滚到没执行该事务之前的状态

事务有以下四个特性:

  1. 原子性(A): 对于一个事务内的所有操作,要么都正常完成提交,要么都回滚,是由 MySQL 的 undo log 日志实现的
  2. 一致性©: 是指事务在执行之前和执行之后,数据库都要满足一种完整性约束,在逻辑上的数据一致性,例如小明有 500,小红有 500,小明转给小红 300 ,最后两个人的钱之和仍然应该为 1000,是由 A I D 共同实现的
  3. 持久性(I): 对于一个事务执行完过后,更改的数据要永久落盘到磁盘当中,是由 MySQL 的 redo log 日志实现的
  4. 隔离性(D): 多个事务共同执行的过程中,各个事务互不影响,由 MVCC 实现

2. 事务并行会发生什么

2.1 脏读

当一个事务正在执行当中,修改了一个数据,此时还未提交,而另一个事务读到这个数据了,当一个事务读到没有提交的数据,称之为脏读,因为没有提交的数据随时会回滚,所以这个数据是没有意义的

2.2 不可重复读

当一个事务正在执行过程当中,首先读到一个数据 A,此时有其他事务修改了这个数据并提交了数据,然后第一个事务再读,发现更之前不一样了,当一个事务多次读一个数据,出现不同的结果,称之为不可重复读

2.3 幻读

幻读和不可重复读类似,不同的是不可重复的是读取的数据不同,而幻读是读取的数据数量不同

3 隔离级别

上面事务对数据库的危害严重性排序:脏读 > 不可重复读 > 幻读

如何解决事务并行带来的危害,MySQL 提供了4种隔离级别来解决这些事务问题

  1. 读未提交: 可以读取没有提交的数据,三种危害都可能出现;直接获取数据,没有额外的处理
  2. 读已提交: 只读取已经提交的数据,脏读不会出现;利用 Read View 实现
  3. 可重复读: 只读取事务开始时候的数据,幻读可能会出现,这是 MySQL 的默认隔离级别;利用 Read View 实现
  4. 串行化: 事务和事务之间串行执行,三种危害都不会出现;通过加同步锁实现

4 Read View 在 MVCC 里如何工作的?

都提交和串行化都十分好理解,而中间两种隔离级别需要 Read View,MVCC 以及 undo log 实现

4.1 Read View 是什么

Read View 是一个当前整个数据库的快照,首先肯定不能够直接把数据库整个数据快照一份,那么每生成一份 Read View,数据库就增加一倍容量,那肯定相当恐怖,而 Read View 的实现方式是将提交事务的时候的整个事务情况做一个快照,有以下 4 个字段

  1. creator_trx_id 创建这个 RV 的事务 ID
  2. m_ids 创建事务的时候,活跃的事务 ID 列表
  3. min_trx_id 创建事务的时候,活跃的事务 ID 列表的最小值
  4. max_trx_id 创建事务的时候,活跃的事务 ID 列表的最大值 + 1

光知道 RV 的 trx_id 没有作用,这里还得提一个东西,数据的隐藏字段: trx_id 和 roll_pointer;trx_id 表示这条数据属于哪个事务创建的,而 roll_pointer 指向的就是历史数据

利用 RV 和 隐藏字段就可以获取到当前快照对应的数据,而这个行为就叫做 MVCC

4.2 MVCC 原理

MVCC 的原理是可见性算法,而可见性算法基于以下几条原则

  1. 如果当前数据的 trx_id 小于 min_trx_id,说明这个数据是在创建事务之前就存在了,对当前这个事务是可见的

  2. 如果当前数据的 trx_id 大于等于 max_trx_id,说明这个数据是在创建事务之后才出现的,对当前这个事务是不可见的

  3. 如果当前数据的 trx_id 小于 min_trx_id,说明这个数据是在创建事务之前就存在了,对当前这个事务是可见的

  4. 如果当前数据的 trx_id 大于等于 min_trx_id,小于 max_trx_id,需要进一步判断是不是在 m_ids 列表当中

    4.1 如果在 m_ids 列表当中,说明这个事务仍然存活着,还没有被提交,对当前这个事务是不可见的

    4.2 如果不在 m_ids 列表当中,说明这个事务已经被提交,对当前这个事务是可见的

5 可重复读和读已提交是如何实现的?

  1. 可重复读就是每次读取的数据是一样,不会因为事务的提交而变化,所以他会在创建事务的时候生成一个快照,然后就根据这个快照的数据进行事务执行

  2. 读已提交每执行一个操作,就会生成一个新的快照,将 m_ids 中已经提交的事务剔除掉

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值