首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >MySQL可重复读隔离级别及更新丢失现象

MySQL可重复读隔离级别及更新丢失现象
EN

Stack Overflow用户
提问于 2018-11-30 18:17:40
回答 2查看 4.2K关注 0票数 1

高性能Java持久性书的6.3.3.3节中,它写道,在MySQL可重复读取隔离级别中,丢失更新现象是可能的。这是截图:

假设以下条件(隔离级别是可重复读取的):

代码语言:javascript
复制
              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)并执行回滚吗?还是提交将成功导致更新丢失?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-11-30 20:48:47

我是问题中提到的书的作者。

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

  • 脏读
  • 不可重复读取

该标准没有提到丢失的更新,因为该标准是在2PL (两相锁定)是事实上的并发控制机制时设计的。

如果使用2PL,那么可重复的读取隔离级别确实会阻止丢失更新

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

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

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

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

票数 7
EN

Stack Overflow用户

发布于 2022-08-10 06:59:24

如果我知道的是正确的,MySQL在可重复读取隔离级别使用MVCC。

顺便说一句,MVCC本身并不能防止更新丢失。

因此,在可重复读取隔离级别。对于MySQL,我们必须使用使用独占锁的select ... for update,这样才能防止丢失的更新。

杰菲。

PostgreSQL还使用MVCC。

在postgreSQL的可重复读取隔离级别上,它使用了第一次更新赢策略,因此在以后的事务B更新X之前更新了X的早期事务A将获胜,如果A成功提交,则B必须进行回滚。如果A失败并回滚,则B可以成功提交。

MySQL和postgreSQL都在读取可重复隔离级别使用MVCC,但是它们对于如何解决丢失的更新问题有不同的策略。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53562850

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档