什么是不可重复读和幻像读之间的区别?(What is the difference between

2019-06-25 12:41发布

什么是不可重复读和幻读之间的区别?

我已阅读维基百科隔离(数据库系统)的文章 ,但我有几个疑问。 在下面的例子中,将发生的事情: 不可重复读幻读

事务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

另一个疑问是,在上述例子中,其中隔离级别应使用? 为什么?

Answer 1:

维基百科 (对于此有很大的和详细的例子):

阿非重复读时,当事务的过程中,一排被检索两次且行内的值读取之间不同。

时,在一个事务的过程中,两个相同的查询被执行时,会发生幻像读,和由所述第二查询返回的行的集合是从所述第一不同。

简单的例子:

  • 用户A运行相同的查询两次。
  • 在此期间,用户B运行的事务,并提交。
  • 非重复读:该A行用户A已经查询具有不同的值的第二时间。
  • 幻读:查询中的所有的行具有相同的值之前和之后, 但正在选择的不同的行 (由于B已删除或插入的一些)。 例如: select sum(x) from table; 将返回不同的结果,即使没有受影响的行本身已被更新,如果行已添加或删除的。

在上面的例子,这隔离级别被使用?

什么隔离级别你需要取决于你的应用。 有很高的成本到“更好的”隔离电平(如减少并发)。

在你的榜样,你不会有一个幻象,因为你从一个单行(按主键标识)只选择。 你可以有不可重复的读取,因此,如果这是一个问题,你可能希望有防止隔离级别。 在Oracle中,事务A还可以发出一个SELECT FOR UPDATE,然后事务B不能,直到完成更改行。



Answer 2:

一个简单的方法,我喜欢去想它是:

这两种不可重复和幻象读取都从不同的事务,之后您的交易开始已经提交,然后由你的交易读取数据修改操作的事情。

不可重复读是当你的交易读取另一个事务提交的更新 。 同一行现在有比它当你的交易开始不同的值。

幻象读取类似,但是从提交的内页阅读和/或从另一个事务删除时。 还有,因为你开始交易已经消失新的行或列。

脏读类似于不可重复和幻读,但涉及到读未提交的数据,当一个UPDATE,INSERT,或从另一事务中删除被读取发生,以及其他事务尚未提交的数据。 它是阅读“进行中”的数据,这可能是不完整的,并且可能从来没有真正被提交。



Answer 3:

正如上文这篇文章中, 不可重复读异常如下所示:

  1. Alice和Bob启动两个数据库事务。
  2. Bob的读取后记录和标题列值为交易。
  3. 爱丽丝修改特定职位记录的酸价值的称号。
  4. 爱丽丝提交了数据库事务。
  5. 如果Bob的重新读取记录后,他将观察不同版本的表行。

在这篇文章中关于幻像读 ,你可以看到,这一反常现象可能发生如下:

  1. Alice和Bob启动两个数据库事务。
  2. Bob的读取所有与后一行的1标识符值相关联的post_comment记录。
  3. 爱丽丝增加了其与具有1的标识符值的交行相关联的新post_comment记录。
  4. 爱丽丝提交了数据库事务。
  5. 如果Bob的重新读取具有POST_ID列值等于1 post_comment记录,他将观察不同版本的结果集。

所以,虽然不可重复读适用于单排, 幻影阅读是关于一个范围的满足给定的查询过滤条件的记录。



Answer 4:

阅读现象

  • 脏读 :从另一个事务读取数据UNCOMMITED
  • 不可重复读 :从读取已提交的数据UPDATE从另一个事务查询
  • 幻影读 :从读取提交数据INSERTDELETE从另一个事务查询

注意 :从另一个事务DELETE语句,也有造成在某些情况下非重复读取的概率非常低。 它发生在当DELETE语句不幸的是,除去对当前事务中查询非常同一行。 但是,这是一种罕见的情况下,与远更不可能在拥有数百万行的每个表的数据库发生。 含有交易数据表通常具有在任何生产环境高数据量。

此外,我们可以观察到,更新可能是在大多数使用情况,而不是实际的INSERT或删除更频繁的工作(在这种情况下, 非重复读取的危险仅保留- 幻象读取是不可能在这些情况下)。 这就是为什么更新从INSERT,DELETE区别对待,并将所得的异常也被命名不同。

还有与处理的INSERT,DELETE操作,而不仅仅是处理更新相关的附加处理成本。


不同的利益隔离级别

  • READ_UNCOMMITTED防止无关。 这是零隔离级别
  • READ_COMMITTED防止只有一个,即脏读
  • REPEATABLE_READ防止两个异常:脏读和不可重复读
  • SERIALIZABLE防止所有三个异常:脏读,不可重复的读取和幻象读取

那么为什么不直接设置在任何时候都SERIALIZABLE交易? 那么,答案对上述问题是:SERIALIZABLE设置使交易速度 ,这是我们又不想。

事实上交易时间消耗在以下速度:

SERIALIZABLE> REPEATABLE_READ> READ_COMMITTED> READ_UNCOMMITTED

所以READ_UNCOMMITTED设置是最快的。


摘要

实际上,我们需要分析的使用情况,因此,我们优化了交易时间,还可以防止大部分的异常决定的隔离级别

请注意,在默认情况下数据库具有REPEATABLE_READ设置。



Answer 5:

有一个在这两种隔离级别之间实行差别。
对于“不可重复读”,则需要行锁定。
对于“幻象”,需要范围的锁,即使一个表锁。
我们可以通过实现这两个层面两阶段锁定协议。



Answer 6:

与不可重复读的系统,事务A的第二个查询的结果将反映在事务B更新 - 它会看到新的金额。

在一个系统,允许幻象读取,如果事务B分别以插入新的行与ID = 1,事务A将看到当执行第二查询的新行; 即虚读不可重复读的一个特例。



Answer 7:

接受答案表示最重要的是,两者之间所谓的区别其实并不显著可言。

如果一排“被检索两次,行内的值之间的读取差异”,那么他们是不是同一行(不正确的RDB讲同样的元组),它是那么确实是定义还有的情况是“集合由所述第二查询返回的行与所述第一不同的”。

至于“该隔离级别应使用”的问题,更多的数据是至关重要有人在什么地方,更多的将是可序列化是唯一合理的选择的情况下。



Answer 8:

我想有间非repeateable读取和幻像读一些差异。

非repeateable意味着有拖交易A和B,如果B能看到A的修改,所以可能发生脏读,所以我们让B A提交后注意到A的修改。

有新的问题:我们假设B通知书的的变形例的承诺之后,就意味着修改其B拿着,有时B就再读一行行的值,所以B将获得与第一次不同的新价值,我们得到的,我们把它叫做非repeateable,来处理这个问题,我们让在B记住一些东西(因为我不知道会怎样还记得)当B开始。

让我们来想想新的解决方案,我们可以看到有新的问题为好,因为我们假设B记住一些东西,所以发生在一个什么时,B不能受到影响,但是当B要插入一些数据表和B检查表,以确保没有记录,但是这个数据已经被插入,那么也许会出现一些错误。 我们把它叫做幻影读。



Answer 9:

非重复读是隔离级别和幻象读取(读取由其他事务提交的值)的一个概念(例如读脏读或快照读取的类型)。 不可重复读隔离级别允许幻象但不脏读或快照读取。



文章来源: What is the difference between Non-Repeatable Read and Phantom Read?