MYSQL - 事务

事务的四大特性是什么?

事务的四大特性是ACID,即原子性、一致性、隔离性和持久性。

原子性:事务是一个原子操作单元,其对数据的修改,要么全部执行,要么全部不执行。
持久性:一个事务一旦提交,它对数据库中数据的改变就应该是永久性的,后续的操作或故障不应该对其产生影响。
隔离性:指的是一个事务的执行不能被其他事务干扰,即一个事务内部的操作及使用的数据对其他的并发事务是隔离的。
一致性:事务开始前和事务结束后,数据库的完整性限制未被破坏。一致性包括两个方面的内容,分别是约束一致性和数据一致性。

什么是 WAL

WAL(Write Ahead Log)预写日志,是数据库系统中常见的一种手段,用于保证数据操作的原子性和持久性。

在计算机科学中,「预写式日志」(Write-ahead logging,缩写 WAL)是关系数据库系统中用于提供原子性和持久性(ACID 属性中的两个)的一系列技术。在使用 WAL 的系统中,所有的修改在提交之前都要先写入 log 文件中。

事务的实现

ACID 4 个特性中有3个与WAL 有关系,都需要通过Redo、Undo 日志来保证。

事务的原子性保证

原子性:事务是一个原子操作单元,其对数据的修改,要么全部执行,要么全部不执行。
事务的原子性是通过Redo log(全部执行) 和Undo log(全部不执行)保证的。

每写一个事务,都会修改Buffer Pool,从而产生相应的Redo/ Undo
日志这些日志信息会被记录到日志文件中。在MySQL 中,任何Buffer
Pool 中的数据页被刷到磁盘之前,都会优先写入到日志文件中,如果
Buffer Pool 中的数据提交(commit),此时数据库挂了,那么在数
据库再次启动之后,可以通过Redo 日志将其恢复出来,以保证脏页
的数据不会丢失。如果数据没有提交(no commit),此时数据库挂
了,就需要通过Undo 来实现。
commit 前 undo log 来恢复
commit 后 redo log 来恢复

事务的持久性保证

持久性:指的是一个事务一旦提交,它对数据库中的改变就应该是永久性的,后续的操作或者故障不应该对其有任何影响,不会丢失。
事务的持久性是通过Redo log 和 WAL 实现的。
MySQL 的持久性也与WAL技术相关,redo log 在系统crash 重启之类的情况时,可以修复数据,从而保障事务的持久性。通过原子性可以保证逻辑上的持久性。通过原则性可以保障逻辑上的持久性,通过存储引擎的数据刷盘可以保障物理上的持久性。
在这里插入图片描述

事务的隔离性保障

隔离性:指的是一个事务的执行不能被其他事务干扰,即一个事务内部的操作及使用的数据对其他的并发事务时隔离的。
InnoDB 支持的隔离性有4种,隔离性从低到高分别为:读未提交、读已提交、可重复读、串行化。
锁和多版本并发控制(MVCC)技术就是用于保障隔离性的。

事务的隔离级别

在这里插入图片描述

脏读(Dirty Read)

读取到了未提交的数据(如果事务这时候回滚了,那么第二个事务就读到了脏数据)

原因可能有:
(1)有一个交叉的事务有新的commit,导致了数据的改变;
(2)一个数据库被多个实例操作时,同一事务的其他实例在该实例处理其间可能会有新的commit。
在这里插入图片描述

不可重复读

同一个事务中,对于同一数据,执行完全相同的select语句时可能看到不一样的结果。
在这里插入图片描述

幻读

当用户读取某一范围的数据行时,另一个事务又在该范围内插入了新行,当用户再读取该范围的数据行时,会发现有新的“幻影” 行;
InnoDB存储引擎通过多版本并发控制(MVCC,Multiversion Concurrency Control)机制解决了该问题。
在这里插入图片描述

幻读和不可重复读的区别

不可重复读 (update)

重点是修改:在同一事务中,同样的条件,第一次读的数据和第二次读的数据不一样。(一个事务多次读取同一范围内数据时,另外一个发生了事务发生update操作并提交了)。数据变化。

幻读 (insert and delete)

重点在于新增或者删除:在同一事务中,同样的条件,,第一次和第二次读出来的记录数不一样。(一个事务多次读取同一条数据时,另外一个发生了事务发生insert,delete操作并提交了。insert操作一条新数据并不会影响刚才被读的那条数据。)。行数变化。

MVCC

MVCC (多版本并发控制),是指在数据库中为了实现高并发的数据
访问,对数据进行多版本处理,并通过事务的可见性来保证事务能
看到自己应该看到的数据版本。

作用是如果某条记录正在被修改,则可以并发读取该记录的历史版本而不必阻塞等待读锁的释放。其实现方式是通过Undo Log 和 Read View 实现的,可以读取Undo Log 里的历史版本,ReadView 用来控制哪个历史版本里是对当前事务可见的。

在MVCC 并发控制中,读操作可以分为两类:快照读与当前读。
快照读(MVCC下):读取的是记录的可见版本(可能是历史版本),不用加锁。(select)
当前读(行锁,间隙锁,临键锁):读取的是记录的最新版本,并且当前读返回的记录,都会加上锁,保证其他事务不会再并发修改这条记录。(insert, update, select … for update…)

一致性非锁定读
一致性非锁定读是指再Innodb 存储引擎通过多版本控制读取当前
数据库中行数据的方式。

如果读取的行正在执行DELETE 或者UPDATE 操作,这时读取操作不会因此去等待行上锁的释放。相反的,InnoDB 会去读取行的一个最新可见快照。
在这里插入图片描述

不同隔离级别下访问数据
RC 和 RR 

在这里插入图片描述
RC 是不可重复读,所以Id 会读成3
RR 是可重复读,所以Id 会读成1

Read View

Read View 就是事务进行快照读的时候产生的读视图(Read View),
在RC 隔离级别下,是每个快照读都会生成并获取新的Read View;
在RR 的隔离级别下,则是同一个事务中的第一个快照才会创建Read View,之后的快照读获取的都是同一个Read View。

Read View 就是一个数据结构,包含4个字段

  • m_ids: 当前活跃的事务编号集合
  • min_trx_id: 最小获取的事务编号
  • max_try_id: 预分配事务编号,当前最大事务编号 + 1
  • creator_trx_id:ReadView 创建者的事务编号
MVCC 实现原理

在这里插入图片描述

案例

RR : select 1 = ‘张三’ select 1 = ‘张三’
RC : select 1 = ‘张三’ select 1 = ‘张小三’
在这里插入图片描述
在这里插入图片描述

Undo Log 会被删除,但不是立即删除,MySQL 确保版本链数据不再被“引用”后再进行删除。

案例下的read view
RC (读已提交)

再每一次执行快照读的时候生成Read View

在这里插入图片描述

RR(可重复读)

仅在第一次执行快照读时生成 Read View,后续快照读复用

在这里插入图片描述

版本链数据访问规则

在这里插入图片描述

特殊案例

连续多次快照读,Read View 会产生复用,没有幻读问题。
特例:当两次快照读之间存在当前读,Read View 会重新生成导致产生幻读。
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值