当前位置: 首页 > 知识库问答 >
问题:

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

施季
2023-03-14

不可重复读取和幻像读取有什么区别?

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

####交易A

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

# # # #输出:

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

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

共有3个答案

巴学潞
2023-03-14

不可重复读取异常如下所示:

    < li>Alice和Bob启动了两个数据库事务。 < li>Bob读取post记录,标题列值为Transactions。 < li>Alice将给定文章记录的标题修改为ACID的值。 < li>Alice提交了她的数据库事务。 < li >如果Bob重新读取post记录,他将观察到此表格行的不同版本。

幻影读取异常可能发生如下情况:

  1. Alice和Bob启动两个数据库事务
  2. Bob's读取与标识符值为1的post行相关联的所有post_comment记录。
  3. Alice添加了一个新的post_comment记录,该记录与标识符值为1的post行相关联。
  4. Alice提交她的数据库事务
  5. 如果Bob重新读取post_id列值等于1的post_comment记录,他将观察到该结果集的不同版本

因此,虽然不可重复读取适用于单行,但幻影读取是关于满足给定查询过滤条件的一系列记录。

西门飞翮
2023-03-14

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

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

不可重复读取是指事务从另一个事务读取已提交的更新。现在,同一行的值与事务开始时的值不同。

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

脏读类似于非可重复读取和幻像读取,但与读取未提交的数据有关,当读取来自另一个事务的UPDATE、INSERT或DELETE,而另一个事务尚未提交数据时,就会发生脏读。它正在读取“正在进行”的数据,这些数据可能不完整,也可能永远不会真正提交。

唐炳
2023-03-14

来自维基百科(其中有很好和详细的例子):

当在事务过程中,一行被检索两次并且行内的值在读取之间有所不同时,就会发生不可重复的读取。

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

简单的例子:

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

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

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

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

 类似资料:
  • 我目前正在阅读《高性能MySQL,第二版》,试图理解MySQL中的事务隔离。 下面是他们对这两个事务隔离级别的解释。 阅读提交 大多数数据库系统(但不是MySQL!)的默认隔离级别是READ COMMITTED。它满足了之前使用的隔离的简单定义:事务将只看到在开始时已经提交的事务所做的更改,并且在它提交之前,它的更改不会对其他人可见。这个级别仍然允许所谓的不可重复读取。这意味着您可以运行相同的语句

  • 根据 SQL 标准,可重复读取应防止模糊读取和脏读,而可序列化还应防止幻像读取。 根据MySQL文档: 默认情况下,InnoDB以可重复读取事务隔离级别运行。在这种情况下,InnoDB使用下一键锁进行搜索和索引扫描,这可以防止幻像行(参见14.2.2.5的“使用下一键锁避免幻像问题”一节)。 那么,如果可重复读取也可以防止幻像读取,那么序列化可以提供什么回报呢? Serializable是否可以防

  • pyspark新手,希望将csv文件读取到数据帧。似乎不能让人读。有什么帮助吗? ()中的Py4JJavaError回溯(最近一次调用)----

  • 我试图将/etc/passwd文件(1,6)中的两个字段读入数组。 我可以将字段设置为变量,但不能设置为数组。 这段代码将获取1000以上的所有用户,并返回用户和主目录。

  • 我使用Spring kafka 2. x读取来自kafka的消息。 我的问题是,如果我的方法在我的kafkalistener方法中花费了一段时间,那么kafka会发送相同的消息两次,这对我来说是个问题。我想要什么,如果我从Kafka读到消息,kafka不会向我发送这条消息第二次值,如 max.poll.interval.ms 不保证一次阅读消息。在Spring启动中实现一次阅读策略的正确方法是什么

  • 问题内容: 从这个甲骨文的Java教程: 当事务A检索行,事务B随后更新该行,事务A随后再次检索同一行时,将发生不可重复的读取。事务A两次检索同一行,但看到不同的数据。 脏读和不可重复读之间有什么区别?是不是同一回事?由于其他人的更新而阅读错误的结果? 提前致谢。 问题答案: 完全相同的页面解释了什么是脏读: 访问尚未提交的更新值被视为脏读,因为该值可能会回滚到其先前的值。如果读取的值稍后会回滚,