Como posso garantir que apenas uma cópia de um procedimento esteja em execução no Oracle?

10

Temos a necessidade de garantir que apenas uma cópia de um procedimento específico esteja em execução no Oracle. Se já estiver em execução e um usuário tentar abrir outro, deverá ocorrer um erro.

Qual é o melhor método para fazer isso?

rfusca
fonte

Respostas:

12

Você pode fazer isso com DBMS_LOCKum bloqueio exclusivo.

Veja o seguinte procedimento:

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

Teste (sessão 1):

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

(Obviamente retorna quando DBMS_LOCK.sleep()retorna).

Teste (sessão 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>

Obviamente você precisa GRANT EXECUTE ON DBMS_LOCK TO YOURUSER;.

Philᵀᴹ
fonte
2

Use uma tabela de 'bloqueio'.

Quando o procedimento iniciar, verifique se há um valor conhecido na tabela, se presente, não vá mais longe e saia de proc. Caso contrário, escreva o valor na tabela, execute o procedimento, exclua o valor e saia normalmente.

Stuart Moore
fonte
Essa é uma boa solução para muitos sistemas, mas neste caso especial, Phil se encaixa melhor, eu acho.
Dez13
1

Quando meus clientes têm uma solicitação que possui uma lógica comercial única como essa, tento mudar a questão e perguntar por que isso é necessário.

A melhor maneira de garantir que apenas uma cópia esteja em execução é não permitir que os usuários executem o procedimento. Se esse procedimento é tão especial, seu uso deve ser restrito ao dba / developers.

Outra maneira é executar este procedimento apenas como um trabalho. Adicione uma verificação no procedimento para ver se algum trabalho chamando isso está em execução. Se estiverem, pare o processamento e registre a ocorrência.

kevinsky
fonte