是否有可能使oracle数据库过程忽略commit语句?

时间:2013-06-20 05:53:39

标签: java oracle jdbc plsql transactions

我正在研究与遗留系统编写的Oracle PL / SQL集成的Java应用程序。不幸的是,我无法改变这个遗留系统。该系统的问题在于有时将COMMIT语句写入过程。但这导致我无法在我的应用程序级别上正确处理事务。

那么是否可以使oracle数据库程序忽略commit语句?

我发现在PL / SQL过程尝试提交时,在连接开始时执行ALTER SESSION DISABLE COMMIT IN PROCEDURE会导致异常。但是有可能让Oracle在不改变PL / SQL代码的情况下忽略提交吗?

6 个答案:

答案 0 :(得分:6)

我认为你不能那样做。您必须向这些过程添加一个参数,例如“do commit”,默认值为true。你用参数设置为false来调用它们。如果它们是嵌套的,则传递参数值。这样,遗留代码的行为仍然相同,但您可以获得事务控制。

答案 1 :(得分:6)

我正在与Oracle合作9年。我还检查了有关您的问题的未记录参数,我很确定,没有办法让Oracle忽略存储过程的提交。

但是,理由上,您可以使用Oracle的闪回功能(例如闪回数据库或闪回表)将整个数据库或单个表重置为事务开始之前的状态。但请注意,这只能按照您的需要运行,如果您是唯一一个在闪回的对象上进行任何更改的人。这通常是不现实的。顺便说一下,您还需要考虑闪回功能不是为支持这种情况而设计的,因此在您需要闪回任何内容时,应用程序的性能将不是最理想的。 但如果您别无选择,这可能是解决问题的一种方法。

答案 2 :(得分:2)

最好的办法是改变pl / sql程序而不影响当前功能。换句话说,添加一个新参数以允许用户忽略提交,但默认为现有功能(提交)。我在类似的情况下做到了这一点并且效果很好。

所以,你有类似的东西:

create or replace procedure some_proc(
    i_num in number, -- existing parameter
    i_commit in number default 1) -- perform commit? 0=false, else true
as

begin
  -- some DML here

  if (i_commit <> 0) then
    commit;
  end if;

end;

确保将此新参数添加到参数列表的末尾。因此,对于i_commit,您的应用程序将传递0(false)。

希望有所帮助。

答案 3 :(得分:0)

  

我在做ALTER SESSION DISABLE COMMIT IN PROCEDURE时发现   在连接开始时将导致PL / SQL过程异常   正试图提交。

是的,该语句的记录行为是在程序尝试发出提交时强制执行ORA-00034异常。我认为它确实是一个测试的东西,用于识别嵌入式提交的程序。

我认为广泛认为存储过程发布提交是不好的做法。对事务的控制必须属于调用堆栈的顶部。

不幸的是,没有办法忽略那些嵌入式提交。您将不得不重新编写PL / SQL例程,或者在调用代码中编写一些变通方法(例如,异常处理程序会发出额外的DML以反转已提交的更改)。

答案 4 :(得分:0)

知道程序的作用会有所帮助。 但是,假设该过程修改了有限数量的表中的数据(这是我们在PLSQL中主要做的事情),您可以尝试在该模式上运行闪回查询:

FLASHBACK TABLE TABLE_NAME到TIMESTAMP(TO_DATE('06 -SEP-2012 23:59:59','DD-MON-YYYY HH24:MI:SS'));

您可以将时间字符串“06-SEP-2012 23:59:59”设置为JAVA代码中调用过程之前的时间。

这是一个糟糕的解决方法,但值得一试,我猜

答案 5 :(得分:0)

  

我正在研究与遗留系统集成的Java应用程序   编写Oracle PL / SQL。不幸的是我无法改变这一点   遗留系统。

嗯,这闻起来像政治......“不要触摸它,它有效!”我猜。 :(

事实上,正如@Tilman Fliegel(和其他人)已经说过的那样,很可能无法忽视COMMIT陈述。如果是的话,在你的代码库中它将是一个非常难看的疣。

我不擅长政治,但我会说如果你不能使用也不能改变,那么就是不要使用这个。我的意思是:

  • 如果由于其他(旧的,不可变的)系统使用它们而无法更改您的程序,则复制它们,然后修改/重构您的副本,直到您对它感到满意为止。如果您能够使您的版本与之兼容,那么您甚至可以为其他(旧)系统提供一种方法,以便在之后/如果它们被重构时使用您的版本:只需引入“遗留模式”输入参数或其他,cf 。其他答案。
  • 如果由于无法理解/测试而无法更改代码,那么这是一个主要问题。它甚至可以更安全地将其丢弃并从头开始(如果你能够这样做的话)。

但也许试图忽略COMMIT更容易。人类很难重构......;)