【发布时间】:2019-05-02 22:09:03
【问题描述】:
在High Performance Java Persistence book 的 6.3.3.3 部分中写道,丢失更新现象在 MySQL 可重复读取隔离级别中是可能的。这是截图:
假设如下(隔离级别为 REPEATABLE READ):
tx1 | tx2
-----------------------------------------------------------------------------------
START TRANSACTION; |
SELECT * FROM test WHERE id = 1; |
( say, DB_TRX_ID = 7 at this moment) |
|
| START TRANSACTION;
| SELECT * FROM test WHERE id = 1;
| UPDATE test SET name="x" WHERE id = 1;
| COMMIT;(say, makes DB_TRX_ID = 10)
|
UPDATE test SET name="y" WHERE id = 1;|
COMMIT;
问题:
在 tx1 提交时,MVCC 是否会检测到行版本(DB_TRX_ID)不再等于 7(而不是 10)并执行回滚?还是提交成功导致更新丢失?
【问题讨论】:
-
MVCC 本质上是乐观的,因为查询会在实现中推进,直到发生提交冲突。但这并不意味着乐观锁定是相关的。你一直在问关于 MySQL 的问题,提到不恰当的锁定和其他错误的期望。不要问“不应该”——要给出答案,我们必须再写一个演示文稿——这太宽泛了,当你不理解它时,我们该怎么办?取而代之的是:准确地解释您认为根据特定演示文稿的理由会发生什么事情。然后我们可以告诉你你第一次出错的地方。
-
请use text, not images/links, for text (including code, tables & ERDs)。使用链接/图像仅是为了方便补充文本和/或无法在文本中给出的内容。永远不要给出没有图例/键的图表。 PS 这里的意思是把表格作为文本给出。但是您还需要在帖子中提供我们回答问题所需知道的任何内容。因此,要么引用相关的内容(作为文本),要么复制不合法,然后改述。那么,关于泄漏的业务是什么?我们还需要从该链接中了解什么?
-
我在哪里提到你说的锁定不当? tx1 选择一行,然后 tx2 更新并提交该行,然后 tx1 更新同一行并提交。所以我问在 tx1 提交时 MVCC 是否检查行版本是否已更新,因为他选择了行并进行回滚(称为乐观锁定),还是提交成功导致丢失更新?怎么了?
-
请通过帖子编辑而非 cmets 进行澄清。 (解释所有您认为正在发生的步骤。)关于“我在哪里提到不恰当的锁定”:“MySQL MVCC 不应该使用数据库级别的乐观锁定来防止丢失更新”。
标签: mysql database relational-database repeatable-read