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