【问题标题】:Rollback not working from Stored Procedure从存储过程回滚不起作用
【发布时间】:2012-06-18 12:41:39
【问题描述】:

我正在使用 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。

【问题讨论】:

  • 你想回滚什么?另一个会话正在锁定该资源,因此您的会话无法锁定它。您的 rollback 无法移除其他会话持有的锁定...
  • 我相信ROLLBACK 声明是有效的;它正在按照规范做它应该做的一切。如果您遇到 ORA-00054 异常,那么您的会话没有获得行锁,因为来自另一个会话的锁冲突。

标签: sql oracle plsql oracle10g


【解决方案1】:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-11
    • 2017-03-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多