我在理解数据库(Oracle)中的读取一致性时遇到问题。
假设我是一家银行的经理。一个客户有一把锁(我不知道)并且正在做一些更新。现在,在他获得锁定后,我正在查看他们的帐户信息并尝试对其进行一些操作。但由于读取一致性,我将看到客户获得锁定之前存在的数据。那么这不会影响我获得的投入以及我在此期间将要做出的决定吗?
我在理解数据库(Oracle)中的读取一致性时遇到问题。
假设我是一家银行的经理。一个客户有一把锁(我不知道)并且正在做一些更新。现在,在他获得锁定后,我正在查看他们的帐户信息并尝试对其进行一些操作。但由于读取一致性,我将看到客户获得锁定之前存在的数据。那么这不会影响我获得的投入以及我在此期间将要做出的决定吗?
关于读取一致性的要点是:假设客户回滚他们的更改?或者假设这些更改由于违反约束或某些系统故障而失败?
在客户成功提交更改之前,这些更改不存在。您可能基于幻读或脏读做出的任何决定都不会比您描述的场景更有效。事实上,它们的有效性较低,因为这些变化是不完整的,因此是不一致的。具体示例:如果客户的更改包括存款和取款,如果您在他们存款但尚未取款时查看了账户,您的决定有多有效?
另一个例子:一个长时间运行的批处理更新组织中每个员工的工资。如果您对员工的工资进行查询,您真的想要一份报告,其中显示一半员工的工资是最新的,一半的员工是旧工资的吗?
编辑
读取一致性是通过使用 UNDO 表空间(旧实现中的回滚段)中的信息来实现的。当一个会话从另一个会话正在更改的表中读取数据时,Oracle 检索已由该第二个会话生成的 UNDO 信息,并将其替换为呈现给第一个会话的结果集中的更改数据。
如果阅读会话是一个长时间运行的查询,它可能会失败,因为臭名昭著的ORA-1555: snapshot too old
. 这意味着包含组装读取一致视图所需信息的 UNDO 范围已被覆盖。
锁与读一致性无关。在 Oracle 中,写入不会阻塞读取。锁的目的是防止其他进程试图更改我们感兴趣的行。
对于拥有大量用户的系统,用户可能会长时间“持有”锁,通常使用Optimistic Offline Lock 模式,即使用 UPDATE ... WHERE 语句中的版本。
您可以使用日期、版本 ID 或其他内容作为行版本。也可以使用虚拟列 ORA_ROWSCN,但您需要先阅读它。
当记录由于更改或显式锁定语句而被锁定时,会在该块的标题中创建一个条目。这称为 ITL(感兴趣的事务列表)。当您来阅读该块时,您的会话会看到这一点并知道从回滚段获取读取一致副本的位置。