【问题标题】:Difference between non-repeatable read vs dirty read不可重复读与脏读的区别
【发布时间】:2013-08-20 07:05:00
【问题描述】:

来自thisoracle java教程:

当事务 A 检索一行时发生不可重复读取, 事务 B 随后更新该行,事务 A 稍后更新 再次检索同一行。事务 A 检索同一行 两次但看到不同的数据。

脏读和不可重复读有什么区别?这不是一回事吗?别人更新导致读错结果?

提前致谢。

【问题讨论】:

    标签: java database jdbc transactions


    【解决方案1】:

    完全相同的页面解释了脏读是什么:

    访问尚未提交的更新值被视为脏读,因为该值可能会回滚到其先前的值。如果您读取的值稍后回滚,则您将读取无效值。

    因此,不可重复读取包括读取两个不同的已提交值,而脏读包括读取尚未提交的值。完全不同。

    【讨论】:

    • 这怎么可能呢?我的意思是在事务完成后,防止不可重复读取的唯一方法是即使在提交之后也保持锁定......无论如何迟早会完成另一个连接(B),它将如何防止更新A 先前检索到的行
    • 或者也许每次只有 1 个连接可能会写入 DBMS。因此,只要有一个与 DBMS 的活动连接,就没有其他连接可以真正更新那些特定行的数据库。(直到第一个连接关闭)我是对的吗?
    • 仅在事务期间保证可重复读取:您启动事务 T1,读取 A1,然后另一个事务 T2 将 A1 修改为 A2 并提交,然后第一个事务 T1 重新读取值,并且仍然读取 A1。那是可重复阅读。当然,另一个在 T2 提交后第一次读取值的事务 T3 将读取已提交的值 A2。要了解它是如何由您的数据库实现的,请阅读其文档。他们中的大多数人使用MVCC,AFAIK。
    【解决方案2】:

    来自here:-

    脏读发生在一个事务读取另一个事务写入的数据时, 未提交,交易。脏读的危险在于 其他事务可能永远不会提交,留下原始事务 带有“脏”数据。

    不可重复读取发生在一个事务试图访问 相同的数据两次,第二个事务修改了数据之间的数据 第一个事务的读取尝试。这可能会导致第一个 事务读取相同数据的两个不同值,导致 原始读取不可重复。

    【讨论】:

    • 这怎么可能呢?我的意思是在事务完成后,防止不可重复读取的唯一方法是即使在提交之后也保持锁定......无论如何迟早会完成另一个连接(B),它将如何防止更新A 之前检索到的行
    • 或者也许每次只有 1 个连接可能会写入 DBMS。因此,只要有一个与 DBMS 的活动连接,就没有其他连接可以真正更新那些特定行的数据库。(直到第一个连接关闭)我是对的吗?
    • 不可重复读取是指一个事务无法第二次读取,除非另一个事务更改该行。在执行 select 语句时,当未获取读取锁时会发生不可重复读取。不可重复读取可能发生在需要由提交冲突影响的事务时,必须回滚是放松的。
    【解决方案3】:

    一张图片值一千字。

    在上图中,语句的流程是这样的:

    1. Alice 和 Bob 启动两个数据库事务。
    2. Alice 修改给定帖子记录的标题。
    3. Bob 读取未提交的帖子记录。
    4. 如果 Alice 提交了她的事务,一切都很好。但如果 Alice 回滚,那么 Bob 将看到数据库事务日志中不再存在的记录版本。

    这种异常只有 Read Uncommitted 隔离级别才允许,并且由于对数据完整性的影响,大多数数据库系统都提供了更高的默认隔离级别。

    【讨论】:

      【解决方案4】:

      我和你以前一样困惑。

      在我阅读了您帖子中的答案后,我决定从 mysql doc 中找出答案。

      从 mysql 阅读文档后,我认为让我们感到困惑的是理解的角度。我们认为“tran A 更改了一条记录而没有提交,而 tran B 前后读取了两个不同的数据,这确实是一个'脏数据'和'不可重复读取'”,我们感到困惑的是因为我们从两个交易行为的结果。

      但是,正确的角度是:“脏读”是一个两次交易的事情,而“不可重复读”完全是一个一次交易的事情。

      这是什么意思?例如,如果你是一个交易,我是你之后的一个交易。你读了一个 X,我把它更新为 Y,然后你再读一次。

      对我们来说,你已经读取了一个脏数据,因为我没有提交,也许我想回滚。我让你读数据。

      对你自己来说,在你自己的事务中,你读取了两个不同的数据,这是一个不可重复的数据。

      有点冗长。可能有帮助。

      参考: 1.https://dev.mysql.com/doc/refman/8.0/en/glossary.html#glos_dirty_read
      2.https://dev.mysql.com/doc/refman/8.0/en/glossary.html#glos_non_repeatable_read

      【讨论】:

      猜你喜欢
      • 2016-12-21
      • 2012-06-18
      • 2017-08-24
      • 1970-01-01
      • 2019-06-16
      • 1970-01-01
      • 2016-07-13
      • 1970-01-01
      • 2012-11-02
      相关资源
      最近更新 更多