我是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以及我们组织使用的自定义错误异常处理包。
本质上,它将回滚导致错误的部分,但是一旦它回滚部分,它将继续执行事务的其余部分(并且不会回滚先前执行的代码块)。
如果这没有意义,请告诉我 - 并提前感谢您的帮助!
答案 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;