不可重复读取和幻像读取有什么区别?
我已经阅读了维基百科上的隔离(数据库系统)文章,但我有一些疑问。在下面的示例中,会发生什么:不可重复读取和幻像读取?
####交易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
另一个疑问是,在上面的例子中,应该使用哪个隔离级别?为什么?
不可重复读取异常如下所示:
幻影读取异常可能发生如下情况:
因此,虽然不可重复读取适用于单行,但幻影读取是关于满足给定查询过滤条件的一系列记录。
我喜欢思考的一个简单方法是:
不可重复读取和幻像读取都与来自不同事务的数据修改操作有关,这些操作是在事务开始后提交的,然后由事务读取。
不可重复读取是指事务从另一个事务读取已提交的更新。现在,同一行的值与事务开始时的值不同。
幻象读取类似,但从另一个事务的提交INSERTS和/或DELETES读取时。有一些新行或自您开始事务以来已消失的行。
脏读类似于非可重复读取和幻像读取,但与读取未提交的数据有关,当读取来自另一个事务的UPDATE、INSERT或DELETE,而另一个事务尚未提交数据时,就会发生脏读。它正在读取“正在进行”的数据,这些数据可能不完整,也可能永远不会真正提交。
来自维基百科(其中有很好和详细的例子):
当在事务过程中,一行被检索两次并且行内的值在读取之间有所不同时,就会发生不可重复的读取。
和
在事务处理过程中,当执行两个相同的查询,并且第二个查询返回的行集合与第一个不同时,就会发生幻像读取。
简单的例子:
从表中选择和(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两次检索同一行,但看到不同的数据。 脏读和不可重复读之间有什么区别?是不是同一回事?由于其他人的更新而阅读错误的结果? 提前致谢。 问题答案: 完全相同的页面解释了什么是脏读: 访问尚未提交的更新值被视为脏读,因为该值可能会回滚到其先前的值。如果读取的值稍后会回滚,