Puoi usare il dbms_job
(o dbms_scheduler
) per inviare lavori che verranno eseguiti in parallelo. Se stai usando dbms_job
, l'invio dei lavori farà parte della transazione, quindi i lavori inizieranno una volta completata la transazione.
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 stai usando dbms_scheduler
, la creazione di un nuovo lavoro non è transazionale (ovvero ci sarebbero commit impliciti ogni volta che si crea un nuovo lavoro), il che potrebbe causare problemi con l'integrità transazionale se nella transazione in cui viene chiamata questa procedura viene svolto altro lavoro. D'altra parte, se stai usando dbms_scheduler
, potrebbe essere più semplice creare i lavori in anticipo ed eseguirli semplicemente dalla procedura (o utilizzare dbms_scheduler
per creare una catena che esegua il lavoro in risposta a qualche altra azione o evento come mettere un messaggio in coda).
Ovviamente, con entrambe le soluzioni, dovresti quindi creare l'infrastruttura per monitorare l'avanzamento di questi tre lavori, supponendo che ti interessi quando e se hanno esito positivo (e se generano errori).
Se intendi utilizzare DBMS_SCHEDULER
- Non è necessario utilizzare SQL dinamico. Puoi abbandonare il
EXECUTE IMMEDIATE
e chiama semplicemente ilDBMS_SCHEDULER
le procedure del pacchetto direttamente come faresti con qualsiasi altra procedura. - Quando chiami
RUN_JOB
, è necessario passare un secondo parametro. Iluse_current_session
parametro controlla se il lavoro viene eseguito nella sessione corrente (e si blocca) o se viene eseguito in una sessione separata (nel qual caso la sessione corrente può continuare e fare altre cose). Dato che vuoi eseguire più lavori in parallelo, dovresti passare un valore difalse
. - Sebbene non sia richiesto, sarebbe più convenzionale creare i lavori una sola volta (con
auto_drop
impostato su false) e quindi eseguili dalla tua procedura.
Quindi probabilmente vorresti creare i lavori al di fuori del pacchetto e quindi la tua procedura diventerebbe semplicemente
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;