0

sqldeveloperを使用して「select*from table_name where att1='some_value'forupdate」クエリを使用して行のロックを取得しています。また、例外が発生した場合に同じ行でロールバックを使用してロックを解放しようとしている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は、更新用のselectを使用してロックを取得したが、ロールバックを実行していない場合は常に-2を返します。

4

1 に答える 1

4

ロックを取得したSQLDeveloperセッションとは異なるセッションでストアドプロシージャを実行している場合、ロールバックを発行してもロックは解放されません。SQL Developerセッション(セッションA)はロックを保持しているため、ストアドプロシージャが実行されているセッション(セッションB)がロックに影響を与えることはありません。セッションAのみがロールバックを発行してロックを解除できます。

ロックを取得したSQLDeveloperセッションと同じセッションでストアドプロシージャを実行している場合SELECT ... FOR UPDATE、現在のセッションがすでにロックを保持しているため、ストアドプロシージャのステートメントは例外を生成しません。つまり、ストアドプロシージャがEXCEPTIONブロックに入ることがなく、を発行することもありませんROLLBACK

于 2012-06-18T14:49:20.717 に答える