6

现在我们用于插入记录集的过程是这样的:

(请注意,“记录集”是指一个人的记录以及他们的地址、电话号码或任何其他连接表)。

  1. 开始交易。
  2. 插入一组相关的记录。
  3. 如果一切都成功,则提交,否则回滚。
  4. 返回到步骤 1 获取下一组记录。

我们应该做更多这样的事情吗?

  1. 在脚本开头启动事务
  2. 为每组记录启动一个保存点。
  3. 插入一组相关记录。
  4. 如果有错误则回滚到保存点,如果一切成功则继续。
  5. 在脚本开头提交事务。

在遇到 ORA-01555 的一些问题并阅读了一些 Ask Tom 文章(如这篇文章)之后,我正在考虑尝试第二个过程。当然,正如 Tom 所指出的,开始一项新事务应该由业务需求来定义。第二个过程值得尝试,还是一个坏主意?

4

2 回答 2

5

事务应该是一个有意义的工作单元。但是什么构成工作单元取决于上下文。在 OLTP 系统中,一个工作单元将是一个人,以及他们的地址信息等。但听起来好像您正在实现某种形式的批处理,即加载大量的人。

如果您遇到 ORA-1555 问题,几乎可以肯定是因为您有一个长时间运行的查询,提供正在由其他事务更新的数据。在循环内提​​交有助于循环使用 UNDO 段,因此往往会增加您赖以提供读取一致性的段被重用的可能性。因此,不这样做可能是一个好主意。

是否使用 SAVEPOINTs 是解决方案是另一回事。我不确定在您的情况下会给您带来什么优势。当您使用 Oracle10g 时,也许您应该考虑使用批量DML 错误日志记录

Alternatively you might wish to rewrite the driving query so that it works with smaller chunks of data. Without knowing more about the specifics of your process I can't give specific advice. But in general, instead of opening one cursor for 10000 records it might be better to open it twenty times for 500 rows a pop. The other thing to consider is whether the insertion process can be made more efficient, say by using bulk collection and FORALL.

于 2009-10-03T21:07:10.437 回答
1

一些想法...

  1. 在我看来,asktom 链接的要点之一是适当调整回滚/撤消的大小以避免 1555。有什么原因这是不可能的吗?正如他所指出的,购买磁盘比编写/维护代码来处理绕过回滚限制要便宜得多(尽管在阅读了 36Gb 驱动器的 250 美元价格标签后,我不得不再三考虑——该线程始于 2002 年!摩尔定律的好例证!)
  2. 此链接 (Burleson)显示了保存点的一个可能问题。
  3. 在您的第二种情况下,您的交易实际上是第 2、3 和 5 步吗?如果是这样,这就是我要做的 - 提交每笔交易。对我来说听起来有点像场景 1 是一个事务集合?
于 2009-10-03T19:39:32.407 回答