Du kan använda dbms_job
(eller dbms_scheduler
)-paket för att skicka in jobb som kommer att köras parallellt. Om du använder dbms_job
, kommer att skicka in jobben att vara en del av transaktionen så jobben startar när transaktionen är klar.
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;
Om du använder dbms_scheduler
, att skapa ett nytt jobb är inte transaktionellt (dvs. det skulle finnas implicita commits varje gång du skapade ett nytt jobb) vilket kan orsaka problem med transaktionsintegriteten om det finns annat arbete som görs i transaktionen där denna procedur anropas. Å andra sidan, om du använder dbms_scheduler
, kan det vara lättare att skapa jobben i förväg och helt enkelt köra dem från proceduren (eller att använda dbms_scheduler
för att skapa en kedja som kör jobbet som svar på någon annan åtgärd eller händelse som att lägga ett meddelande i en kö).
Naturligtvis, med båda lösningarna, måste du sedan bygga infrastrukturen för att övervaka framstegen för dessa tre jobb, förutsatt att du bryr dig om när och om de lyckas (och om de genererar fel).
Om du ska använda DBMS_SCHEDULER
- Det finns inget behov av att använda dynamisk SQL. Du kan ta bort
EXECUTE IMMEDIATE
och ring baraDBMS_SCHEDULER
paketets procedurer direkt precis som du skulle göra med vilken annan procedur som helst. - När du ringer
RUN_JOB
måste du skicka in en andra parameter.use_current_session
parametern styr om jobbet körs i den aktuella sessionen (och blockerar) eller om det körs i en separat session (i vilket fall den aktuella sessionen kan fortsätta och göra andra saker). Eftersom du vill köra flera jobb parallellt måste du skicka in värdetfalse
. - Även om det inte krävs, skulle det vara mer vanligt att skapa jobben en gång (med
auto_drop
inställd på false) och kör dem sedan från din procedur.
Så du skulle förmodligen vilja skapa jobben utanför paketet och då skulle din procedur bara bli
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;