【问题标题】:Transactions in OracleOracle 中的事务
【发布时间】:2016-10-10 14:59:36
【问题描述】:

我在 Oracle 数据库中作为第三方 API 的存储过程很少,我想在一个事务中链接这些 api 调用。我可以做吗? 据我了解that answer 我可以使用保存点。但是,如果这些 API 已经有提交语句,它是否有效? Oracle 是否会回滚嵌套提交?

另外,Oracle 如何处理保存点和并发? IE。如果我们有图表:

connection#1 (my api call)              connection#2 (3rd party api call)
savepoint sp1;
                                        savepoint sp2;
update t1 where id=1 set val=1;         update t1 where id=2 set val=2;
                                        commit; --done
call bad_stored_proc();
rollback to sp1;

这里会发生什么?回滚会仅影响行 (id=1,val=1),还是同时影响两行?

【问题讨论】:

  • 您无法回滚已经提交的内容。所以在这种情况下,调用的顺序很重要,以及你想要回滚的究竟是什么。显然,您将无法回滚供应商 SP 的承诺工作。所以你必须专注于你自己的代码。你的代码是否依赖于厂商的 Sp 执行结果?它在调用顺序中的位置。它是第一个/最后一个还是在调用供应商的 SP 的中间?话虽如此,当您回滚时,您可以避免调用供应商的 sps,或者如果不可避免地在它们之后进行清理(应该非常小心,取决于那些 SP 所做的事情)。
  • 如果他们(供应商的 SP)提交,这可能是一个“错误”或者供应商非常迫切地需要这样做,因此如果您选择这样做,您需要非常小心地清理它们这样做。

标签: oracle


【解决方案1】:

Oracle 不会回滚嵌套提交。他们承诺。

您能做的最好的事情(也不是那么好)就是将第 3 方 API 包装在一个过程中,并用 PRAGMA AUTONOMOUS_TRANSACTION 标记该过程。这将限制第 3 方 API 只提交自己的工作。这意味着,如果您回滚,则将提交第 3 方事务工作,但不会提交您所做的任何其他工作。

这通常是一件非常糟糕的事情,因为它会使您的数据在绝大多数设计情况下逻辑上被破坏。我提到它是在不太可能的情况下面临的设计情况,您可以侥幸逃脱。

【讨论】:

    【解决方案2】:

    如果第三方过程在过程中调用了commit,那么在不修改过程本身的情况下,没有办法将它们全部作为一个事务运行。

    Oracle 不支持嵌套提交或嵌套事务。提交意味着——您正在承诺将更改写入数据库并失去回滚更改的选项。

    您可以使用会话参数来检查第三方过程是否包含任何提交语句。

    alter session disable commit in procedure; 
    

    使用此设置,任何尝试提交的过程都会抛出错误消息。*

    • 感谢 Matthew McPeak 纠正了我对该参数作用的误解。

    【讨论】:

      猜你喜欢
      • 2012-09-13
      • 1970-01-01
      • 1970-01-01
      • 2015-08-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-09
      相关资源
      最近更新 更多