Du kan bruge dbms_job
(eller dbms_scheduler
) pakke for at indsende job, der kører parallelt. Hvis du bruger dbms_job
, vil indsendelse af opgaverne være en del af transaktionen, så opgaverne starter, når transaktionen er gennemført.
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;
Hvis du bruger dbms_scheduler
, er oprettelse af et nyt job ikke transaktionsbestemt (dvs. der ville være implicitte commits, hver gang du oprettede et nyt job), hvilket kan forårsage problemer med transaktionsintegriteten, hvis der er andet arbejde, der udføres i transaktionen, hvor denne procedure kaldes. På den anden side, hvis du bruger dbms_scheduler
, kan det være lettere at oprette opgaverne på forhånd og blot køre dem fra proceduren (eller at bruge dbms_scheduler
at oprette en kæde, der kører jobbet som svar på en anden handling eller hændelse, såsom at sætte en besked i en kø).
Med begge løsninger skal du selvfølgelig bygge infrastrukturen til at overvåge fremskridtene for disse tre job, forudsat at du bekymrer dig om, hvornår og om de lykkes (og om de genererer fejl).
Hvis du skal bruge DBMS_SCHEDULER
- Der er ingen grund til at bruge dynamisk SQL. Du kan droppe
EXECUTE IMMEDIATE
og kald bareDBMS_SCHEDULER
pakkens procedurer direkte ligesom du ville gøre med enhver anden procedure. - Når du ringer til
RUN_JOB
, skal du indtaste en anden parameter.use_current_session
parameter styrer, om jobbet kører i den aktuelle session (og blokerer), eller om det kører i en separat session (i hvilket tilfælde den aktuelle session kan fortsætte og gøre andre ting). Da du vil køre flere job parallelt, skal du indtaste værdienfalse
. - Selvom det ikke er påkrævet, ville det være mere konventionelt at oprette jobs én gang (med
auto_drop
indstillet til falsk), og kør dem derefter fra din procedure.
Så du ville nok gerne skabe jobs uden for pakken, og så ville din procedure bare blive til
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;