存储数据快照
说了半天,在给用户显示先前版本的数据同时,Oracle是如何允许其他用户修改数据的呢?其实,只要某一用户启动了一宗修改数据的交易,之前的数据映像就会被写到一个特殊的存储区域。这种“前映像”用来向任何查询数据的用户提供一致的数据库视图。这样,当其他用户在修改数据的时候,在以上的测试中我们就能看到尚未发生变更的薪金数据。这个特殊的存储区域在哪里呢?这个问题的答案就跟你正在使用的Oracle版本有关了。在 Oracle 8i及其以前版本中会为这一目的创建特殊的回滚段。然而,这种举措会给数据库管理员(DBA)带来管理和调整数据段的工作负担。例如,DBA必须确定为此需要的数据段的数量以及大小等。假如回滚段没有正确配置,那么对交易而言它们就可能不得不排队等待回滚段中出现必要的数据空间。
Oracle 9i就不同了,这是Oracle的最新版本,Oracle实现了一种新特性,这就是所谓的undo表空间,它有效地消除了以上的管理复杂性。虽然回滚段仍然可以继续使用,但是,DBA现在可以选择创建undo表空间的方式令Oracle自己管理“前映像”的复杂空间分配。Oracle的这种方法对程序员具有重要意义。因为回滚空间不是无限的,所以,更新交易的数据快照会取代先前交易的映像。因此,如果必要的回滚段被其他交易的映像覆盖的话。运行时间较长的查询操作就可能产生“ snapshot too old”错误。
下面举个可能发生的案例。假设在上午11:59的时候某位职员开始更新John Doe帐务的交易。这宗交易在下午12:01被提交。同时,下午12:00某财务经理开始查询所有的客户帐务报表和当月收费总计。因为客户很多,所以这一查询操作很费了点时间,但是不论这次操作到底执行了多久,反正它检索出的结果就是下午12:00数据库中存在的数据。如果包含John Doe帐务前映像的回滚空间在查询执行到该客户名字的时候被覆盖则查询返回错误消息。Oracle的解决方案当然更为合理,在抽象意义上提供了相比SQL Server更佳的数据一致性。在执行Oracle查询的时候无须担心较长的查询操作会锁定重要的交易。但是,在两种数据库同时支持海量用户的情况下也很难证明Oracle是否就能真正实现具体条件下的数据一致性。