Oracleでプロシージャのコピーが1つだけ実行されていることをどのように確認できますか?


10

Oracleでは、特定のプロシージャのコピーが1つだけ実行されていることを確認する必要があります。それがすでに実行されていて、ユーザーが別のものを開こうとすると、エラーになります。

これを行うための最良の方法は何ですか?

回答:


12

DBMS_LOCKと排他ロックでこれを行うことができます。

次の手順を参照してください。

CREATE OR REPLACE PROCEDURE myproc
IS
  lockhandle VARCHAR2(128);
  retcode NUMBER;
BEGIN
  DBMS_LOCK.ALLOCATE_UNIQUE('myproclock',lockhandle);

  retcode:=DBMS_LOCK.REQUEST(lockhandle,timeout=>0, lockmode=>DBMS_LOCK.x_mode);

  IF retcode<>0
  THEN
    raise_application_error(-20000,'myproc is already running');
  END IF;

  /* sleep so that we can test with a 2nd execution */
  DBMS_LOCK.sleep(1000);

  retcode:=DBMS_LOCK.RELEASE(lockhandle);

END myproc;
/

テスト(セッション1):

SQL> BEGIN
  2  myproc();
  3  END;
  4  /

(明らかに戻るときにDBMS_LOCK.sleep()戻ります)。

テスト(セッション2):

SQL> BEGIN
  2  myproc();
  3  END;
  4  /
BEGIN
*
ERROR at line 1:
ORA-20000: myproc is already running
ORA-06512: at "PHIL.MYPROC", line 12
ORA-06512: at line 2


SQL>

明らかにあなたはする必要がありGRANT EXECUTE ON DBMS_LOCK TO YOURUSER;ます。


2

「ロック」テーブルを使用します。

プロシージャが開始したら、テーブルに既知の値があるかどうかを確認します。存在する場合は、それ以上進んでprocを終了します。存在しない場合は、値をテーブルに書き込み、プロシージャを実行してから、値を削除して通常どおり終了します。


これは多くのシステムにとって良い解決策ですが、この特別なケースではフィルの方が適していると思います。
dezso 2012

1

私のクライアントがこのような独自のビジネスロジックを持つリクエストを持っている場合、私は質問を変えて、なぜこれが必要なのか尋ねます。

1つのコピーのみが実行されていることを確認する最良の方法は、ユーザーがプロシージャをまったく実行できないようにすることです。この手順が特別な場合は、その使用をdba / developersに制限する必要があります。

別の方法は、このプロシージャをジョブとしてのみ実行することです。プロシージャにチェックを追加して、これを呼び出すジョブが実行されているかどうかを確認します。その後、処理を停止し、発生をログに記録します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.