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;

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

4

1 回答 1

4

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

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

于 2012-06-18T14:49:20.717 回答