2012-06-18 15 views
0

我正在使用sqldeveloper使用「select * from table_name where att1 ='some_value'for update」來獲取行鎖。並且從SP嘗試在異常情況下在同一行上使用回滾來釋放鎖,但回滾不在SP中工作。但是,如果我從sqldeveloper的回滾工作正常,並釋放鎖。回滾沒有從存儲過程中工作

請指導我,如果我做錯了什麼。這是我的存儲過程。

DECLARE 
    resource_busy EXCEPTION; 
    resource_busy2 EXCEPTION; 
    PRAGMA EXCEPTION_INIT (resource_busy, -30006); 
    PRAGMA EXCEPTION_INIT (resource_busy2, -00054); 
BEGIN 
    counter := 0; 

    SELECT COUNT (*) 
    INTO counter 
    FROM TBLACCOUNT 
    WHERE TBLACCOUNT.ACCOUNT_ID = RPAD (ACCT_NUM, 20, ' '); 

    IF (counter > 0) THEN 
    BEGIN 
     SELECT TBLACCOUNT.AVAILABLE_BALANCE, TBLACCOUNT.ACTUAL_BALANCE 
     INTO Avail_Bal, Curr_Bal 
     FROM TBLACCOUNT 
     WHERE TBLACCOUNT.ACCOUNT_ID = RPAD (ACCT_NUM, 20, ' ') 
     FOR UPDATE WAIT 1; 
    EXCEPTION 
     WHEN resource_busy OR resource_busy2 
     THEN 
     ROLLBACK;      --This rollback is not working. 
     RETURN -2; 
    END; 
    END IF; 
END; 

此SP返回-2每當我獲取鎖使用選擇更新但不進行回滾。

+1

大寫鎖定題目! – Shackrock

+6

你想回滾什麼?另一個會話對該資源持有鎖定,因此您的會話無法鎖定它。你的'rollback'不能刪除不同會話持有的鎖... –

+0

我相信'ROLLBACK'語句正在工作;它正在按照規範做它應該做的所有事情。如果遇到ORA-00054異常,則由於來自另一個會話的鎖定衝突,您的會話不會獲得行鎖定。 – spencer7593

回答

4

如果您在與獲取鎖的SQL Developer會話不同的會話中執行存儲過程,則發出回滾將不會釋放該鎖。 SQL Developer會話(會話A)持有鎖,因此存儲過程正在執行的會話(會話B)確實會影響該會話。只有會話A可以發出回滾並釋放鎖。

如果您在與獲取鎖的SQL Developer會話相同的會話中執行存儲過程,存儲過程中的SELECT ... FOR UPDATE語句將不會生成異常,因爲當前會話已保存該鎖。這意味着存儲過程永遠不會進入EXCEPTION塊,並且永遠不會發出ROLLBACK