From f15b6a7fc1334145b0a87a7345041d3b2926e35c Mon Sep 17 00:00:00 2001 From: wylovely Date: Wed, 28 Oct 2026 14:42:24 +0800 Subject: [PATCH] =?UTF-8?q?fix(typo):=20=E4=BF=AE=E6=AD=A3=E3=80=8C?= =?UTF-8?q?=E4=BA=8B=E7=89=A9=E3=80=8D=E2=86=92=E3=80=8C=E4=BA=8B=E5=8A=A1?= =?UTF-8?q?=E3=80=8D=E7=AC=94=E8=AF=AF=20(close=20#316)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit MySQL 锁与事务章节中 4 处将「事务」误写为「事物」,统一修正。 Closes #316 --- mysql/lock/mysql_lock.md | 2 +- mysql/transaction/mvcc.md | 2 +- mysql/transaction/phantom.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/mysql/lock/mysql_lock.md b/mysql/lock/mysql_lock.md index cc8ca432..d035d0c3 100644 --- a/mysql/lock/mysql_lock.md +++ b/mysql/lock/mysql_lock.md @@ -308,7 +308,7 @@ Next-Key Lock 称为临键锁,是 Record Lock + Gap Lock 的组合,锁定一 ![](https://cdn.xiaolincoding.com/gh/xiaolincoder/mysql/锁/gap锁.drawio.png) -当事务 A 还没提交的时候,事务 B 向该表插入一条 id = 4 的新记录,这时会判断到插入的位置已经被事务 A 加了间隙锁,于是事物 B 会生成一个插入意向锁,然后将锁的状态设置为等待状态(*PS:MySQL 加锁时,是先生成锁结构,然后设置锁的状态,如果锁状态是等待状态,并不是意味着事务成功获取到了锁,只有当锁状态为正常状态时,才代表事务成功获取到了锁*),此时事务 B 就会发生阻塞,直到事务 A 提交了事务。 +当事务 A 还没提交的时候,事务 B 向该表插入一条 id = 4 的新记录,这时会判断到插入的位置已经被事务 A 加了间隙锁,于是事务 B 会生成一个插入意向锁,然后将锁的状态设置为等待状态(*PS:MySQL 加锁时,是先生成锁结构,然后设置锁的状态,如果锁状态是等待状态,并不是意味着事务成功获取到了锁,只有当锁状态为正常状态时,才代表事务成功获取到了锁*),此时事务 B 就会发生阻塞,直到事务 A 提交了事务。 插入意向锁名字虽然有意向锁,但是它并**不是意向锁,它是一种特殊的间隙锁,属于行级别锁**。 diff --git a/mysql/transaction/mvcc.md b/mysql/transaction/mvcc.md index 2894bc1c..236d5a53 100644 --- a/mysql/transaction/mvcc.md +++ b/mysql/transaction/mvcc.md @@ -244,7 +244,7 @@ Read View 有四个重要的字段: 然后事务 B 第二次去读取该记录,**发现这条记录的 trx_id 值为 51,在事务 B 的 Read View 的 min_trx_id 和 max_trx_id 之间,则需要判断 trx_id 值是否在 m_ids 范围内,判断的结果是在的,那么说明这条记录是被还未提交的事务修改的,这时事务 B 并不会读取这个版本的记录。而是沿着 undo log 链条往下找旧版本的记录,直到找到 trx_id 可见的第一条记录(trx_id「小于」事务 B 的 Read View 中的 min_trx_id 值,或者 trx_id 在事务 B 的 Read View 的 min_trx_id 和 max_trx_id 之间,但是不在 m_ids 范围内)**,所以事务 B 能读取到的是 trx_id 为 50 的记录,也就是小林余额是 100 万的这条记录。 -最后,当事物 A 提交事务后,**由于隔离级别时「可重复读」,所以事务 B 再次读取记录时,还是基于启动事务时创建的 Read View 来判断当前版本的记录是否可见。所以,即使事物 A 将小林余额修改为 200 万并提交了事务,事务 B 第三次读取记录时,读到的记录都是小林余额是 100 万的这条记录**。 +最后,当事务 A 提交事务后,**由于隔离级别时「可重复读」,所以事务 B 再次读取记录时,还是基于启动事务时创建的 Read View 来判断当前版本的记录是否可见。所以,即使事务 A 将小林余额修改为 200 万并提交了事务,事务 B 第三次读取记录时,读到的记录都是小林余额是 100 万的这条记录**。 就是通过这样的方式实现了,「可重复读」隔离级别下在事务期间读到的记录都是事务启动前的记录。 diff --git a/mysql/transaction/phantom.md b/mysql/transaction/phantom.md index d420d3a1..a0310278 100644 --- a/mysql/transaction/phantom.md +++ b/mysql/transaction/phantom.md @@ -71,7 +71,7 @@ MySQL 里除了普通查询是快照读,其他都是**当前读**,比如 upd 事务 A 执行了这面这条锁定读语句后,就在对表中的记录加上 id 范围为 (2, +∞] 的 next-key lock(next-key lock 是间隙锁 + 记录锁的组合)。 -然后,事务 B 在执行插入语句的时候,判断到插入的位置被事务 A 加了 next-key lock,于是事物 B 会生成一个插入意向锁,同时进入等待状态,直到事务 A 提交了事务。这就避免了由于事务 B 插入新记录而导致事务 A 发生幻读的现象。 +然后,事务 B 在执行插入语句的时候,判断到插入的位置被事务 A 加了 next-key lock,于是事务 B 会生成一个插入意向锁,同时进入等待状态,直到事务 A 提交了事务。这就避免了由于事务 B 插入新记录而导致事务 A 发生幻读的现象。 ## 幻读被完全解决了吗?