Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

Paralelizando chamadas em PL/SQL


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 o DBMS_SCHEDULER procedimentos do pacote diretamente como faria com qualquer outro procedimento.
  • Quando você chama RUN_JOB , você precisa passar um segundo parâmetro. A use_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 de false .
  • 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;