您可以使用dbms_job
(or 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;