Wie kann ich sicherstellen, dass in Oracle nur eine Kopie einer Prozedur ausgeführt wird?

10

Wir müssen sicherstellen, dass in Oracle nur eine Kopie einer bestimmten Prozedur ausgeführt wird. Wenn es bereits ausgeführt wird und ein Benutzer versucht, ein anderes zu öffnen, sollte ein Fehler auftreten.

Was ist die beste Methode dafür?

rfusca
quelle

Antworten:

12

Sie können dies mit DBMS_LOCKund einem exklusiven Schloss tun .

Siehe das folgende Verfahren:

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;
/

Test (Sitzung 1):

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

(Offensichtlich zurück, wenn DBMS_LOCK.sleep()zurück).

Test (Sitzung 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>

Offensichtlich müssen Sie GRANT EXECUTE ON DBMS_LOCK TO YOURUSER;.

Philᵀᴹ
quelle
2

Verwenden Sie eine Sperrtabelle.

Wenn die Prozedur beginnt, überprüfen Sie die Tabelle auf einen bekannten Wert. Wenn vorhanden, gehen Sie nicht weiter und beenden Sie proc. Wenn nicht, schreiben Sie den Wert in die Tabelle, führen Sie die Prozedur aus, löschen Sie den Wert und beenden Sie ihn wie gewohnt.

Stuart Moore
quelle
Dies ist eine gute Lösung für viele Systeme, aber in diesem speziellen Fall ist Phils Anzug besser, denke ich.
Dekso
1

Wenn meine Kunden eine Anfrage mit einer einzigartigen Geschäftslogik wie dieser haben, versuche ich, die Frage umzudrehen und zu fragen, warum dies erforderlich ist.

Der beste Weg, um sicherzustellen, dass nur eine Kopie ausgeführt wird, besteht darin, die Benutzer die Prozedur überhaupt nicht ausführen zu lassen. Wenn dieses Verfahren so speziell ist, sollte seine Verwendung auf dba / Entwickler beschränkt sein.

Eine andere Möglichkeit besteht darin, diese Prozedur nur als Job auszuführen. Fügen Sie in der Prozedur eine Überprüfung hinzu, um festzustellen, ob Jobs ausgeführt werden, die dies aufrufen. Wenn dies der Fall ist, beenden Sie die weitere Verarbeitung und protokollieren Sie das Auftreten.

kevinsky
quelle