MySQL可重复读取隔离级别和丢失更新现象

MySQL可重复读取隔离级别和丢失更新现象,mysql,database,relational-database,repeatable-read,Mysql,Database,Relational Database,Repeatable Read,在书的6.3.3.3节中写到,在MySQL可重复读取隔离级别中,丢失更新现象是可能的。这是屏幕截图: 假设以下情况(隔离级别为可重复读取): 问题: 在tx1提交时,MVCC是否会检测到行版本(DB_TRX_ID)不再等于7(而是10)并执行回滚?或者提交将成功导致更新丢失?根据SQL标准,可重复读取应防止: 脏书 不可重复读取 该标准没有提到丢失的更新,因为该标准是在事实上的并发控制机制出现时设计的 如果您使用2PL,那么可重复读取隔离级别实际上将防止出现错误 然而,MVCC可以通过一个

在书的6.3.3.3节中写到,在MySQL可重复读取隔离级别中,丢失更新现象是可能的。这是屏幕截图:

假设以下情况(隔离级别为可重复读取):

问题:


在tx1提交时,MVCC是否会检测到行版本(DB_TRX_ID)不再等于7(而是10)并执行回滚?或者提交将成功导致更新丢失?

根据SQL标准,可重复读取应防止:

  • 脏书
  • 不可重复读取
该标准没有提到丢失的更新,因为该标准是在事实上的并发控制机制出现时设计的

如果您使用2PL,那么可重复读取隔离级别实际上将防止出现错误

然而,MVCC可以通过一个元组的多个版本提供可重复的读取,但是,为了防止更新丢失,MVCC还需要事务调度器跟踪某个事务读取的记录的元组修改。显然,InnoDB不是这样工作的

MySQL MVCC不应该使用导致事务回滚的数据库级悲观锁定来防止更新丢失吗

MVCC在可重复读取中不使用任何悲观锁定。唯一采用的锁是聚集索引上采用的gap和next键锁,但这些锁不能防止更新丢失


MySQL仅对Serializable使用悲观锁定,这提供了2PL并发控制模型,即使在使用基于MVCC_的InnoDB存储引擎时也是如此。

根据SQL标准,可重复读取应防止:

  • 脏书
  • 不可重复读取
该标准没有提到丢失的更新,因为该标准是在事实上的并发控制机制出现时设计的

如果您使用2PL,那么可重复读取隔离级别实际上将防止出现错误

然而,MVCC可以通过一个元组的多个版本提供可重复的读取,但是,为了防止更新丢失,MVCC还需要事务调度器跟踪某个事务读取的记录的元组修改。显然,InnoDB不是这样工作的

MySQL MVCC不应该使用导致事务回滚的数据库级悲观锁定来防止更新丢失吗

MVCC在可重复读取中不使用任何悲观锁定。唯一采用的锁是聚集索引上采用的gap和next键锁,但这些锁不能防止更新丢失


MySQL仅对Serializable使用悲观锁定,这提供了2PL并发控制模型,即使在使用基于MVCC_的InnoDB存储引擎时也是如此。

对不起,我应该在问题中编写“乐观锁定”而不是“悲观锁定”。当tx1选择具有MVCC分配版本的行时,比如X,然后tx2提交其更新,然后当tx1提交其自己的更新时,我认为MVCC应该检测到行版本不再是X,从而导致tx1回滚。从您的回答中我了解到,Innodb MVCC在提交期间不会跟踪版本更改,因此Innodb MVCC没有提供乐观锁定,对吗?另外,我已经更新了我的问题。你能同时更新你的答案吗?这只是一个实施细节。唯一标准化的就是那些需要预防的异常情况。因此,根据标准,它们的实施是良好的。如果不研究源代码,就很难说它到底是如何工作的。在更新期间不需要检查行版本,但在提交之前加载的元组时需要检查行版本。请在你的帖子中说明你是这本书的作者。有道理:s/the/mySorry,我应该写“乐观锁定”而不是“悲观锁定“在我的问题上。当tx1选择具有MVCC分配版本的行时,比如X,然后tx2提交其更新,然后当tx1提交其自己的更新时,我认为MVCC应该检测到行版本不再是X,从而导致tx1回滚。从您的回答中我了解到,Innodb MVCC在提交期间不会跟踪版本更改,因此Innodb MVCC没有提供乐观锁定,对吗?另外,我已经更新了我的问题。你能同时更新你的答案吗?这只是一个实施细节。唯一标准化的就是那些需要预防的异常情况。因此,根据标准,它们的实施是良好的。如果不研究源代码,就很难说它到底是如何工作的。在更新过程中不需要检查行版本,但在提交之前加载的元组时。请在您的帖子中注明您是该书的作者。这很有意义:s/the/myMVCC本质上是乐观的,因为在提交冲突发生之前,查询会在实现中进行。但这并不意味着乐观锁定是相关的。你不断地问关于MySQL的问题,不恰当地提到了锁定&还有其他错误的期望。不要问“是不是应该”——为了给出答案,我们必须再写一篇演讲稿——这太宽泛了,当你不明白的时候,我们该怎么办?取而代之的是:准确地解释你认为每一个特定的演示都会发生什么事情。然后我们可以告诉你第一次出错的地方。使用链接/图像仅为方便补充文本和/或文本中无法给出的内容。不要给出没有图例/键的图表。这里的PS表示以文本形式给出表格。但是你也需要在你的帖子里提供我们回答这个问题所需要的任何信息。所以,要么引用相关的内容(如文本),要么如果复制不合法,就重新解释。那么,泄漏的业务是什么?我们还需要从该链接了解什么?我在哪里提到了你所说的不适当锁定?tx1选择一行,然后tx2向上
              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;