2013-09-27 20 views
0

我是Oracle PL/SQL的新手,我試圖使用C#將SQL Server調整爲使用PL/SQL的Oracle自定義Web應用程序來實現多層應用程序。多個程序包調用的PL/SQL回滾事務

我正確地在回滾事務時遇到問題。由於我用於編寫可重用代碼,因此我使用這些類中的包和方法編寫了我的PL/SQL代碼。我的更新過程首先完成驗證,如果驗證成功,則調用一系列各種包方法來完成保存。不幸的是,在更新過程的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

這聽起來比事情要複雜得多。也許有必要這樣做。無論哪種方式,沒有看到你所有的代碼,我們很難給出任何建議。 – APC

+0

APC - 它以何種方式聽起來太複雜?就代碼而言,它與我的代碼具有相同的結構......它只有較少的變量和不同的名稱。我的主要問題是在包方法中執行回滾 - 是否還應回滾調用包方法的父過程中的代碼? –

+1

回滾影響整個交易。除非你有保存點 – APC

回答

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; 
+0

布拉德利 - 感謝您的幫助!我對我的要求感到沮喪的部分原因是他們不允許使用服務器端語言。從HTML到數據庫的所有內容都是用PL/SQL編寫的。我正在努力改變我的思想過程,使用客戶端,業務和數據庫層將其從分層應用程序改爲邏輯上將其分離到PL/SQL代碼中。在PL/SQL中完全創建類似的結構要困難得多。儘管如此,我認爲通過在調用存儲過程中處理它,我可以直接在PL/SQL中完成同樣的事情。謝謝! –

+1

你正確的處理它在你的調用存儲過程中是合適的。樂意效勞! – bdeem

+0

快速注意他人...我認爲這是Raise_application_error而不是raise_application_exception。否則,它效果很好! –