为什么不能更新已被 MySQL 中的另一个事务更新的行

问题描述

我正在尝试了解 MySQL InnoDB 的可重复读取隔离级别。但是当我尝试这两个交易时,它有一种我无法理解的行为。

这是我的测试初始化​​

mysql> SHOW CREATE TABLE `test`;
+-------+---------------------------------------------------------------------------------------+
| Table | Create Table                                                                          |
+-------+---------------------------------------------------------------------------------------+
| test  | CREATE TABLE `test` (
  `ID` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 |
+-------+---------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

mysql> SELECT * FROM `test`;
+----+
| ID |
+----+
|  1 |
+----+
1 row in set (0.00 sec)

mysql> SELECT @@TX_ISOLATION;
+-----------------+
| @@TX_ISOLATION  |
+-----------------+
| REPEATABLE-READ |
+-----------------+
1 row in set,1 warning (0.00 sec)

没有 Tx1 Tx2
1 开始交易 开始交易
2 SELECT * FROM test;# Return 1 SELECT * FROM test;# Return 1
3 SELECT * FROM test WHERE ID = 1 FOR UPDATE;# return 1
4 UPDATE test SET ID = 2 WHERE ID = 1; #好的 UPDATE test SET ID = 3 WHERE ID = 1; # 锁等待
5 SELECT * FROM test;# Return 2 #继续等待
6 提交; #好的 # 查询成功:行匹配:0,更改:0,警告:0
7 SELECT * FROM test;# Return 2 SELECT * FROM test WHERE ID = 1;# Return 1
8 UPDATE test SET ID = 3 WHERE ID = 1; #Query OK:行匹配:0,更改:0,警告:0
9 SELECT * FROM test;# Return 2 SELECT * FROM test;# Return 1
10 UPDATE test SET ID = 3 WHERE ID = 2;#Query OK:行匹配:1,更改:1,警告:0
11 提交; #好的
12 SELECT * FROM test# Return 3 SELECT * FROM test# Return 3

我想知道 MySQL 如何在第 8 和 10 行处理 Tx2 中的 ID=1 和 ID=2。 如果我在 Tx2 的第 4 行使用 UPDATE test SET ID = 3 WHERE ID = 2,即使 Tx1 只持有 ID = 1 的排他锁,仍然需要锁等待?

解决方法

在第 8 步,不再有锁定的记录,因为 TX1 已经完成了一个 COMMIT,并且这会清除锁定。

也不再有 ID=1 的记录,因为它已被更新。

在第 9 步和第 10 步,由于可重复读取,Tx2 无法更新记录。它无法看到 id=2 的记录,也不再找到 id=1 的记录(因为它已经消失/改变了)。

只有在 COMMIT 之后,Tx2 才能看到新的/更改的数据。

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...