回滚无法使用存储过程

时间:2012-06-18 12:41:39

标签: sql oracle plsql oracle10g

我正在使用“select * from table_name获取锁定行,其中att1 ='some_value'用于更新”查询使用sqldeveloper。并且从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;

每当我使用select for update获取锁定而不进行回滚时,此SP返回-2。

1 个答案:

答案 0 :(得分:4)

如果您在与获取锁的SQL Developer会话不同的会话中执行存储过程,则发出回滚将不会释放锁。 SQL Developer会话(会话A)保持锁定,因此执行存储过程的会话(会话B)不会影响该会话。只有会话A可以发出回滚并释放锁定。

如果在与获取锁的SQL Developer会话相同的会话中执行存储过程,则存储过程中的SELECT ... FOR UPDATE语句将不会生成异常,因为当前会话已经保持锁定。这意味着存储过程永远不会进入EXCEPTION块,永远不会发出ROLLBACK