Jak mogę się upewnić, że tylko jedna kopia procedury działa w Oracle?

10

Musimy upewnić się, że tylko jedna kopia konkretnej procedury działa w Oracle. Jeśli jest już uruchomiony, a użytkownik próbuje otworzyć inny, oznacza to błąd.

Jaka jest najlepsza metoda tego?

rfusca
źródło

Odpowiedzi:

12

Możesz to zrobić za DBMS_LOCKpomocą specjalnej blokady.

Zobacz następującą procedurę:

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 (sesja 1):

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

(Oczywiście wraca, gdy DBMS_LOCK.sleep()wraca).

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

Oczywiście, że musisz GRANT EXECUTE ON DBMS_LOCK TO YOURUSER;.

Philᵀᴹ
źródło
2

Użyj tabeli „blokady”.

Gdy procedura się rozpocznie, sprawdź tabelę pod kątem znanej wartości, jeśli jest dostępna, nie idź dalej i wyjdź z proc. Jeśli nie, zapisz wartość do tabeli, wykonaj procedurę, następnie usuń wartość i wyjdź jak zwykle.

Stuart Moore
źródło
To dobre rozwiązanie dla wielu systemów, ale myślę, że w tym szczególnym przypadku garnitur Phila jest lepszy.
dezso,
1

Kiedy moi klienci mają żądanie, które ma unikalną logikę biznesową taką jak ta, staram się odwrócić pytanie i zapytać, dlaczego jest to potrzebne.

Najlepszym sposobem, aby upewnić się, że tylko jedna kopia jest uruchomiona, jest w ogóle nie pozwolić użytkownikom na wykonanie procedury. Jeśli ta procedura jest tak wyjątkowa, to jej użycie powinno być ograniczone do dba / deweloperów.

Innym sposobem jest uruchomienie tej procedury tylko jako zadanie. Dodaj zaznaczenie w procedurze, aby sprawdzić, czy uruchomione są jakiekolwiek zadania wywołujące to. Jeśli tak, zatrzymaj dalsze przetwarzanie i zapisz zdarzenie.

Kevinsky
źródło