Можете да използвате dbms_job
(или dbms_scheduler
) пакет за изпращане на задачи, които ще се изпълняват паралелно. Ако използвате dbms_job
, изпращането на заданията ще бъде част от транзакцията, така че заданията ще започнат, след като транзакцията приключи.
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;
Ако използвате dbms_scheduler
, създаването на нова работа не е транзакционно (т.е. ще има неявни ангажименти всеки път, когато създавате ново задание), което може да причини проблеми с целостта на транзакцията, ако има друга работа, която се извършва в транзакцията, където се извиква тази процедура. От друга страна, ако използвате dbms_scheduler
, може да е по-лесно да създадете заданията предварително и просто да ги стартирате от процедурата (или да използвате dbms_scheduler
за създаване на верига, която изпълнява заданието в отговор на някакво друго действие или събитие, като например поставяне на съобщение на опашка).
Разбира се, при всяко решение ще трябва да изградите инфраструктура, за да наблюдавате напредъка на тези три задачи, като приемем, че ви е грижа кога и дали ще успеят (и дали генерират грешки).
Ако ще използвате DBMS_SCHEDULER
- Не е необходимо да използвате динамичен SQL. Можете да изхвърлите
EXECUTE IMMEDIATE
и просто извикайтеDBMS_SCHEDULER
процедурите на пакета директно, както бихте направили всяка друга процедура. - Когато се обадите на
RUN_JOB
, трябва да предадете втори параметър.use_current_session
параметърът контролира дали заданието се изпълнява в текущата сесия (и блокира) или дали се изпълнява в отделна сесия (в този случай текущата сесия може да продължи и да прави други неща). Тъй като искате да изпълнявате няколко задачи паралелно, ще трябва да подадете стойностfalse
. - Въпреки че не е задължително, би било по-конвенционално да създадете работни места веднъж (с
auto_drop
задайте на false) и след това просто ги стартирайте от вашата процедура.
Така че вероятно бихте искали да създадете работни места извън пакета и тогава вашата процедура просто ще стане
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;