具有多个包调用的PL / SQL回滚事务

时间:2013-09-27 18:20:40

标签: sql oracle plsql transactions rollback

我是Oracle PL / SQL的新手,我正在尝试使用C#将SQL Server从使用PL / SQL的Oracle自定义Web应用程序调整为应用程序的多个层。

我现在遇到了回滚交易的问题。因为我用来编写可重用的代码,所以我使用这些类中的包和方法编写了我的PL / SQL代码。我的更新过程首先完成验证,如果验证成功,则调用一系列不同的包方法来完成保存。不幸的是,在调用Rollback函数时,我在更新过程的EXCEPTION部分中的回滚不会回滚所有内容。我不知道为什么这样做。我的基本代码(虽然由于法律问题不准确)如下:

PROCEDURE SaveApplicationData(
variableName                  IN VARCHAR2 DEFAULT NULL,
--...
seq_id OUT INT )
AS
BEGIN
SET TRANSACTION NAME 'Transaction Name';

  --Save initial program record
  SaveNewRecord(variableName, seq_id);
  IF (seq_id != 0) THEN
    --If saved successfully, seq_id represents record ID
    package_class.secondarySaveMethod(variableName, seq_id);
    second_package_class.anotherSaveMethod(variableName, seq_id);  

END IF;

  COMMIT;
  htp.p('Sequence ID: ' || seq_id);
  htp.p('Saved the record"' || programName || '" successfully!');
EXCEPTION
WHEN OTHERS THEN
 utilityPackage.rollbacktransaction;
END SaveApplicationData;

utilityPackage.rollbacktransaction包含一个ROLLBACK以及我们组织使用的自定义错误异常处理包。

本质上,它将回滚导致错误的部分,但是一旦它回滚部分,它将继续执行事务的其余部分(并且不会回滚先前执行的代码块)。

如果这没有意义,请告诉我 - 并提前感谢您的帮助!

1 个答案:

答案 0 :(得分:1)

来自Oracle之前的SQL Server环境我可以理解这种混淆。 Oracle 使用BEGIN TRANSACTION。相反,为您启动了一项隐式交易。

因此,我相信您的情况SET TRANSACTION NAME不是您想要做的,请参阅 SET TRANSACTION

我建议从包中删除回滚代码并将其放在C#中。提交者应该负责。在C#中使用事务来保证在成功执行包时提交事务。

理想情况下,您的包结构应该更像这样。

declare
  ex_custom EXCEPTION;
  PRAGMA EXCEPTION_INIT( ex_custom, -20001 );
begin
  --Save initial program record
  SaveNewRecord(variableName, seq_id);
  IF (seq_id != 0) THEN
    --If saved successfully, seq_id represents record ID
    package_class.secondarySaveMethod(variableName, seq_id);
    second_package_class.anotherSaveMethod(variableName, seq_id);  
  ELSE
     -- seq_id invalid throw an exception
     RAISE_APPLICATION_ERROR(-20001,'Custom error')
  END IF;

  htp.p('Sequence ID: ' || seq_id);
  htp.p('Saved the record"' || programName || '" successfully!');
EXCEPTION
WHEN ex_custom THEN
  -- if needed we log it
  utility.log_exception;
  -- Raise it for the client to handle
  raise;
END SaveApplicationData;