【发布时间】:2013-08-20 07:05:00
【问题描述】:
来自thisoracle java教程:
当事务 A 检索一行时发生不可重复读取, 事务 B 随后更新该行,事务 A 稍后更新 再次检索同一行。事务 A 检索同一行 两次但看到不同的数据。
脏读和不可重复读有什么区别?这不是一回事吗?别人更新导致读错结果?
提前致谢。
【问题讨论】:
标签: java database jdbc transactions
来自thisoracle java教程:
当事务 A 检索一行时发生不可重复读取, 事务 B 随后更新该行,事务 A 稍后更新 再次检索同一行。事务 A 检索同一行 两次但看到不同的数据。
脏读和不可重复读有什么区别?这不是一回事吗?别人更新导致读错结果?
提前致谢。
【问题讨论】:
标签: java database jdbc transactions
完全相同的页面解释了脏读是什么:
访问尚未提交的更新值被视为脏读,因为该值可能会回滚到其先前的值。如果您读取的值稍后回滚,则您将读取无效值。
因此,不可重复读取包括读取两个不同的已提交值,而脏读包括读取尚未提交的值。完全不同。
【讨论】:
来自here:-
脏读发生在一个事务读取另一个事务写入的数据时, 未提交,交易。脏读的危险在于 其他事务可能永远不会提交,留下原始事务 带有“脏”数据。
不可重复读取发生在一个事务试图访问 相同的数据两次,第二个事务修改了数据之间的数据 第一个事务的读取尝试。这可能会导致第一个 事务读取相同数据的两个不同值,导致 原始读取不可重复。
【讨论】:
一张图片值一千字。
在上图中,语句的流程是这样的:
这种异常只有 Read Uncommitted 隔离级别才允许,并且由于对数据完整性的影响,大多数数据库系统都提供了更高的默认隔离级别。
【讨论】:
我和你以前一样困惑。
在我阅读了您帖子中的答案后,我决定从 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
【讨论】: