非重复读取和幻像读取之间有什么区别?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (156)

非可重复读取和幻像读取之间有什么区别?

我已阅读维基百科隔离(数据库系统)文章,但我有一些疑问。在下面的例子中,会发生什么:非重复读取幻像读取

交易A

SELECT ID, USERNAME, accountno, amount FROM USERS WHERE ID=1

OUTPUT:

1----MIKE------29019892---------5000

交易B

UPDATE USERS SET amount=amount+5000 where ID=1 AND accountno=29019892;
COMMIT;

交易A

SELECT ID, USERNAME, accountno, amount FROM USERS WHERE ID=1

另一个疑问是,在上面的例子中,应该使用哪个隔离级别?为什么?

提问于
用户回答回答于

来自维基百科(有很多详细的例子):

发生不可重复读取时,在事务过程中,行被检索两次,行之间的值在读取之间不同。

当在事务过程中执行两个相同的查询并且第二个查询返回的行集合与第一个查询不同时发生幻像读取。

简单的例子:

  • 用户A运行相同的查询两次。
  • 在这之间,用户B运行一个事务并提交。
  • 不可重复读取:用户A查询的行第二次有不同的值。
  • 幻像读取:查询中的所有行在前后具有相同的值,但选择了不同的行(因为B已删除或插入了一些)。例如:select sum(x) from table;即使没有更新任何受影响的行本身,如果添加或删除了行,也会返回不同的结果。

在上面的例子中,要使用哪个隔离级别?

您需要什么隔离级别取决于您的应用程序。“更好”隔离级别的成本很高(如并发性降低)。

在你的例子中,你不会有幻象读取,因为你只从一行中选择(由主键标识)。你可以有不可重复的读取,所以如果这是一个问题,你可能希望有一个隔离级别来防止这种情况。在Oracle中,事务A也可以发出SELECT FOR UPDATE,然后事务B不能在A完成之前更改该行。

用户回答回答于

我喜欢考虑的一个简单方法是:

非重复读取和幻像读取都与来自不同事务的数据修改操作有关,这些操作在事务开始后提交,然后由您的事务读取。

当您的事务读取来自另一个事务的已提交UPDATES时,不可重复读取。现在,同一行的值与交易开始时的值不同。

幻影读取类似,但是从另一个事务中读取已提交的INSERTS和/或DELETES时。自开始交易以来,有新的行或行已经消失。

脏读非重复和幻读相似,但与读取UNCOMMITTED数据相关,并且在读取另一个事务的UPDATE,INSERT或DELETE时发生,而另一个事务尚未提交数据时发生。它正在阅读“正在进行中”的数据,这些数据可能并不完整,可能永远无法提交。

所属标签

可能回答问题的人

  • HKC

    红客学院 · 创始人 (已认证)

    26 粉丝7 提问5 回答
  • Dingda

    Dingda · 站长 (已认证)

    4 粉丝0 提问3 回答
  • 西风

    renzha.net · 站长 (已认证)

    9 粉丝1 提问3 回答
  • 螃蟹居

    1 粉丝0 提问2 回答

扫码关注云+社区

领取腾讯云代金券