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

Some confusion on the description of read consistency in Oracle

以下是 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.

在此上下文中,一个 "statement" 是一个 DML 语句:单个 SELECTINSERTUPDATEDELETEMERGE .

不是一个PL/SQL块。同样,同一 DML 语句的多次执行(例如,在 PL/SQL 循环中)是分开的 "statements"。如果您需要多个语句或 PL/SQL 块内的一致性,您可以使用 SET TRANSACTION ISOLATION LEVEL SERIALIZABLESET TRANSACTION READ ONLY 来实现。两者都引入了限制。

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

起始条件:table BIG_TABLE 有 1000 万行。

10:00 的用户 A:

SELECT COUNT(*) FROM BIG_TABLE;

10:01 的用户 B:

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

10:02 的用户 B:

COMMIT;

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

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

这是错误的。用户 A 应该获得 1000 万行或 900 万行。 table 中从来没有 9309129 提交 行。发生的事情是,在 Oracle 实际处理删除之前(或在 COMMIT 之前),用户 A 已经读取了用户 B 正在删除的 309,129 行。然后,在用户 B delete/commit 之后,用户 A 的查询不再看到删除的行并停止计数。

由于多版本读取一致性的实现,这种问题在 Oracle 中是不可能的。

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

基本上就是这样 -- Oracle 语句在数据库的一个版本上运行,因为它存在于单个时间点。这个时间点几乎总是语句开始的时间。当该时间点将移动到时间点 "mid statement" 时,存在一些涉及更新的异常情况。但它始终与某个时间点或另一个时间点一致。