我可以用保存点替换在Oracle中启动新事务吗?

时间:2009-10-03 18:49:22

标签: oracle oracle10g commit savepoints ora-01555

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

(并注意“记录集”表示某人的记录及其地址,电话号码或任何其他已连接的表格。)

  1. 开始交易。
  2. 插入一组相关的记录。
  3. 如果一切都成功,则提交,否则回滚。
  4. 返回步骤1以获取下一组记录。
  5. 我们应该做更像这样的事吗?

    1. 在脚本开头处启动交易
    2. 为每组记录启动保存点。
    3. 插入一组相关记录。
    4. 如果出现错误,请回滚到保存点,如果一切都成功,请继续。
    5. 在脚本开头提交事务。
    6. 在ORA-01555遇到一些问题并阅读一些Ask Tom文章(如this one)之后,我正在考虑尝试第二个过程。当然,正如Tom指出的那样,开始新的交易是应该由业务需求定义的。第二个过程值得尝试,还是一个坏主意?

2 个答案:

答案 0 :(得分:5)

交易应该是一个有意义的工作单位。但是,工作单元的构成取决于具体情况。在OLTP系统中,工作单元将是一个人,以及他们的地址信息等。但听起来好像您正在实施某种形式的批处理,这会加载很多人。

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

是否使用SAVEPOINTs解决方案是另一回事。我不确定在你的情况下会给你带来什么好处。在使用Oracle10g时,您应该考虑使用批量DML error logging

或者,您可能希望重写驱动查询,以便它可以处理较小的数据块。如果不了解您的流程细节,我无法提供具体的建议。但总的来说,不是打开10000个记录的一个光标,而是打开它20次,每次打开500行。另一件需要考虑的事情是,是否可以通过使用批量收集和FORALL来提高插入过程的效率。

答案 1 :(得分:1)

一些想法......

  1. 在我看来,问号链接的一个要点就是适当调整回滚/撤消的大小,以避免1555的问题。有什么理由不可能吗?正如他所指出的那样,购买磁盘比编写/维护代码以解决回滚限制要便宜得多(尽管我在阅读了价值250美元的36Gb驱动器之后不得不做一次双重操作 - 该线程始于2002年!摩尔定律的好例子!)
  2. This link (Burleson)显示了保存点可能存在的一个问题。
  3. 您的交易实际上是在第二个场景中的2,3和5步吗?如果是这样,那就是我要做的 - 提交每笔交易。对我来说听起来有点像方案1是一系列交易集合?