Můžete použít dbms_job
(nebo dbms_scheduler
) balíček pro odeslání úloh, které poběží paralelně. Pokud používáte dbms_job
, odeslání úloh bude součástí transakce, takže úlohy se začnou po dokončení transakce.
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;
Pokud používáte dbms_scheduler
, vytvoření nové úlohy není transakční (tj. při každém vytvoření nové úlohy by došlo k implicitním potvrzením), což může způsobit problémy s transakční integritou, pokud se v transakci, kde je tato procedura volána, provádí jiná práce. Na druhou stranu, pokud používáte dbms_scheduler
, může být jednodušší vytvořit úlohy předem a jednoduše je spustit z procedury (nebo použít dbms_scheduler
vytvořit řetězec, který spustí úlohu v reakci na nějakou jinou akci nebo událost, jako je umístění zprávy do fronty).
Samozřejmě, s oběma řešeními budete muset vybudovat infrastrukturu pro sledování průběhu těchto tří úloh za předpokladu, že vás zajímá, kdy a zda budou úspěšné (a zda generují chyby).
Pokud se chystáte použít DBMS_SCHEDULER
- Není potřeba používat dynamické SQL. Můžete se vzdát příkazu
EXECUTE IMMEDIATE
a stačí zavolatDBMS_SCHEDULER
procedury balíčku přímo, stejně jako jakékoli jiné procedury. - Když zavoláte
RUN_JOB
, musíte zadat druhý parametr.use_current_session
parametr řídí, zda se úloha spustí v aktuální relaci (a zablokuje) nebo zda bude spuštěna v samostatné relaci (v takovém případě může aktuální relace pokračovat a dělat jiné věci). Protože chcete spouštět více úloh paralelně, museli byste předat hodnotufalse
. - Ačkoli to není povinné, bylo by konvenčnější vytvořit úlohy jednou (pomocí
auto_drop
nastavte na hodnotu false) a poté je spusťte z vaší procedury.
Pravděpodobně byste tedy chtěli vytvořit úlohy mimo balíček a pak by se vaše procedura stala
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;