java培训机构_南阳清大教育培训机构

java培训机构_南阳清大教育培训机构正文 谈到 MYSQL 的事物 相信大家对这几个概念都不会陌生 四大特性 ACID 并发问题 脏读 不可重复读 幻读 隔离级别 Read Uncommitted 读未提交 Read Committed 读提交 Repeatable Read 可重读 Serializable 可串行化 下面的思维导图可能更表达得清晰 MySQL 的默认事物隔离级别是 RR Repeatable

正文

谈到 MYSQL 的事物, 相信大家对这几个概念都不会陌生:

四大特性:ACID

并发问题

脏读

不可重复读

幻读

隔离级别

Read Uncommitted(读未提交)

Read Committed(读提交)

Repeatable Read(可重读)

Serializable(可串行化)

下面的思维导图可能更表达得清晰😏

MySQL 的默认事物隔离级别是 RR (Repeatable Read) ,可重复读级别是能够解决脏读、不可重复读的这两个事物并发问题的,但是幻读的问题仍会存在,如果使用Serializable的隔离级别,对于高并发的业务来说是不实际的。那么 MySQL 是如何解决幻读这个棘手的问题呢?

没错,MySQL 通过MVCC(多版本并发控制)和Gap Lock(间隙锁)这两个机制解决了幻读的问题~

那么这两种方式具体又是如何实现的呢?

这里我们先讲一下 MySQL 的**”读”的区别**。因为在事物隔离级别中的**“读”**,分为快照读(snapshot read)和当前读(current read)

1. 当前读(current read)
select…lock in share mode (共享读锁) select…for update update , delete , insert

读取的是最新的数据,并且对读取的记录加锁,阻塞其他事物对当前事物查询数据的修改和插入,从而解决幻读。

实现方式:Next-key Locks(临键锁)

官方对临键锁的定义是:

A next-key lock is a combination of a record lock on the index record and a gap lock on the gap before the index record.

简单来说就是 临键锁 = 行记录锁 + 间隙锁

行锁、间隙锁这个锁的概念,下文会介绍。所以这里我们只要知道的是,对于事物的当前读模式,是通过 Gap-Key-Locks 解决的。

2. 快照读(snapshot read)
select * from table

单纯的 select 操作

Read Committed 隔离级别:每次select都生成一个快照读。

Read Repeatable 隔离级别:开启事务后第一个select语句才是快照读的地方,而不是一开启事务就快照读。

实现方式:undolog 和 MVCC

undolog 用于数据的撤回操作,它记录了修改的反向操作,比如,插入对应删除,修改对应修改为原来的数据,通过undo log 可以实现事务回滚,并且可以根据 undo log 回溯到某个特定的版本的数据。

MVCC 就是上文提到的多版本并发控制。

实现方式

MVCC

MVCC 只是工作在两种事务级别底下:

Read Committed

Repeatable Read

MVCC 每行记录后面保存三个隐藏的列,其中其主要作用的有两列

DB_TRX_ID: 记录行数据创建时的事物版本号。每开启一个事物,事物版本号都会递增。

DB_ROLL_PTR: 记录行数据何时过期(或者被删除)。指向前一个版本的 undolog 记录,组成 undo 链表。如果更新了行,则撤消日志记录包含在更新行之前重建行内容所需的信息。

INSERT
插入数据时, DB_TRX_ID 记录的是当前新增数据的事物版本号

DELETE
删除数据时,DB_ROLL_PTR 记录的是当前操作删除的事物版本号

UPDATE

更新数据时,插入一条新的数据,DB_TRX_ID 记录的是当前更新数据的事物版本号

将旧数据的 DB_ROLL_PTR 值更新为当前更新数据的事物版本号

SELECT
查询规则如下:

查找数据行版本号早于当前事务版本号的数据行记录,也就是说(当前的查询的事物版本号 >= DB_TRX_ID 中的值)
这样就能确保事物读取的数据,要么是当前事物已经存在的,要么是当前事物所操作过的。

查找删除版本号要么为NULL,要么大于当前事务版本号的记录。也就是说 (DB_ROLL_PTR IS NULL OR DB_ROLL_PTR > 当前的查询的事物版本号)
这样确保查询出来的数据行记录在事务开启之前没有被删除。

编程小号
上一篇 2025-06-25 21:21
下一篇 2025-07-25 13:11

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/hz/111125.html