对Oracle中读取一致性的描述有些困惑

时间:2018-07-03 12:22:30

标签: sql oracle data-consistency

下面是oracle概念指南中读取一致性的简短摘要。

什么是sql语句,仅一个sql?还是Pl / SQL还是存储过程?任何人都可以帮助我提供一个相反的示例,该示例可以表明读取的不一致之处?

 read consistency 
    A consistent view of data seen by a user. For example, in statement-level read
    consistency the set of data seen by a SQL statement remains constant throughout
    statement execution.

1 个答案:

答案 0 :(得分:4)

在此上下文中,“声明”是一个DML语句:单个SELECTINSERTUPDATEDELETEMERGE

这不是PL / SQL块。同样,同一DML语句的多次执行(例如,在PL / SQL循环中)是单独的“语句”。如果需要在多个语句上或在PL / SQL块中保持一致,则可以使用SET TRANSACTION ISOLATION LEVEL SERIALIZABLESET TRANSACTION READ ONLY来实现。两者都有局限性。

读取不一致的相反示例如下。

开始条件:表BIG_TABLE有1000万行。

用户A在10:00:

SELECT COUNT(*) FROM BIG_TABLE;

用户B在10:01:

DELETE FROM BIG_TABLE WHERE ID >= 9000000;  -- delete the last million rows

用户B在10:02:

COMMIT;

用户A在10:03:查询完成:

COUNT(*)
--------------
9309129

那是错的。用户A应该获得1000万行或900万行。表格中始终没有9309129 committed 行。发生的情况是,在Oracle实际处理删除之前(或在COMMIT之前,用户A已读取用户B删除的309,129行。然后,在用户B删除/提交之后,用户A的查询就停止了查看已删除的行并停止对其进行计数。

由于其实现了多版本读取一致性,因此在Oracle中无法解决此类问题。

在Oracle中,在上述情况下,由于遇到遇到的行已被用户B删除(并提交)的块,所以用户A的查询将使用UNDO数据重建这些块在10:00时的样子:用户A的查询开始时。

基本上就是这样-Oracle语句在单个时间点上存在的数据库版本上运行。该时间点几乎总是语句开始的时间。在某些情况下,涉及更新的情况是该时间点将被移动到时间点“ mid statement”。但是从一个时间点到另一个时间点,它始终是一致的。