我对PL-SQL很陌生,尽管我对其他RDBMS有很多数据库经验。这是我目前的问题。
procedure CreateWorkUnit
is
update workunit
set workunitstatus = 2 --workunit loaded
where
SYSDATE between START_DATE and END_DATE
and workunitstatus = 1 --workunit created;
--commit here?
call loader; --loads records based on status, will have a commit of its own
update workunit wu
set workunititemcount = (select count(*) from workunititems wui where wui.wuid = wu.wuid)
where workunitstatus = 2
所以我看到的行为,有或没有commit语句是我必须执行两次。一旦翻转状态,加载器将在第二次执行时运行。我希望一气呵成。
我很感激oracle智慧的任何一句话。
谢谢!
答案 0 :(得分:4)
何时在批处理过程中提交事务?这是一个很好的问题,尽管它与您发布的代码的问题似乎只是模糊地相关。但无论如何,让我们回答它。
我们需要在PL / SQL过程完成一个工作单元时提交。工作单元是商业交易。这通常是在程序结束时,即EXCEPTION部分之前的最后一个声明。
有时甚至不是。正确提交或回滚的决定在于调用堆栈的顶部。如果我们的PL / SQL是从客户端调用的(可能是用户点击屏幕上的按钮),那么客户端也许应该发出提交。
但批处理过程管理自己的提交(以及错误时的回滚)并非不合理。但重点是唯一最顶层的程序应该发出COMMIT。如果一个过程调用其他过程,那些被调用的程序不应该发出提交或回滚。如果他们应该处理任何错误(日志等)并重新将它们提升到调用程序。让它解码是否回滚。因为所有被调用的过程都在同一个会话中运行,因此在同一个事务中运行:被调用程序中的回滚将还原批处理过程中的所有更改。那是不对的。相同的推理适用于提交。
有时您会阅读有关使用间歇性提交将长时间运行的进程分解为较小单元的建议,例如:每1000个插页。这是一个糟糕的建议有几个原因,并非所有原因都与交易有关。相关的是:
ORA-1555 Snapshot too old
错误的原因。ORA-1002 Fetch out of sequence
错误的原因。因此,“Oracle智慧”的用语是:始终将数据库事务与业务事务对齐,每个工作单元提交一次。
有人提到autonmous transactions是在子流程中发布提交的一种方式。这通常是一个坏主意。在自治事务中进行的更改对其他会话可见,但对我们自己的会话不可见。这很少有意义。它也产生了与我之前讨论过的可重启性相同的问题。
自动交易唯一可接受的用途是记录活动(错误日志,跟踪,审计记录)。无论更广泛的交易发生什么,我们都需要这些数据持续存在。对pragma的任何其他使用几乎肯定是porr设计的一种解决方法,这实际上只会使问题变得更糟。
答案 1 :(得分:0)
您可能不需要在pl / sql过程中提交。您在另一个过程中调用的过程将使用相同的会话,因此您不需要提交。顺便说一句,如果会话回滚或有异常,则必须完全回滚。
答案 2 :(得分:0)
我错误地解决了我的问题。我认为这是一个事务问题,实际上它是我的标志之一未按预期设置。当我期待0时,数字字段为空。
很抱歉。 约什罗宾逊