Você pode usar o
dbms_job
(ou dbms_scheduler
) para enviar trabalhos que serão executados em paralelo. Se você estiver usando dbms_job
, o envio dos trabalhos fará parte da transação, de modo que os trabalhos serão iniciados assim que a transação for concluída. CREATE PACKAGE BODY pkg IS
CREATE PROCEDURE do
IS
l_jobno pls_integer;
BEGIN
dbms_job.submit(l_jobno, 'begin other_pkg.other_proc; end;' );
dbms_job.submit(l_jobno, 'begin other_pkg2.other_proc2; end;' );
dbms_job.submit(l_jobno, 'begin other_pkg3.other_proc3; end;' );
END;
END;
Se você estiver usando
dbms_scheduler
, criar um novo trabalho não é transacional (ou seja, haveria commits implícitos toda vez que você criasse um novo trabalho) o que pode causar problemas com a integridade transacional se houver outro trabalho sendo feito na transação em que esse procedimento é chamado. Por outro lado, se você estiver usando dbms_scheduler
, pode ser mais fácil criar os trabalhos antecipadamente e simplesmente executá-los a partir do procedimento (ou usar dbms_scheduler
para criar uma cadeia que execute o trabalho em resposta a alguma outra ação ou evento, como colocar uma mensagem em uma fila). É claro que, com qualquer uma das soluções, você precisaria construir a infraestrutura para monitorar o progresso desses três trabalhos, supondo que você se importe com quando e se eles são bem-sucedidos (e se geram erros).
Se você for usar
DBMS_SCHEDULER
- Não há necessidade de usar SQL dinâmico. Você pode abandonar o
EXECUTE IMMEDIATE
e basta chamar oDBMS_SCHEDULER
procedimentos do pacote diretamente como faria com qualquer outro procedimento. - Quando você chama
RUN_JOB
, você precisa passar um segundo parâmetro. Ause_current_session
O parâmetro controla se o trabalho é executado na sessão atual (e blocos) ou se é executado em uma sessão separada (nesse caso, a sessão atual pode continuar e fazer outras coisas). Como você deseja executar vários trabalhos em paralelo, você precisaria passar um valor defalse
. - Embora não seja obrigatório, seria mais convencional criar os trabalhos uma vez (com
auto_drop
definido como false) e, em seguida, apenas execute-os a partir do seu procedimento.
Então você provavelmente gostaria de criar os trabalhos fora do pacote e então seu procedimento se tornaria
CREATE PACKAGE BODY pkg IS
CREATE PROCEDURE do
IS
BEGIN
DBMS_SCHEDULER.RUN_JOB('job_other_pkg.other_proc', false);
DBMS_SCHEDULER.RUN_JOB('job_other_pkg2.other_proc2', false);
DBMS_SCHEDULER.RUN_JOB('job_other_pkg3.other_proc3', false);
END;
END;