我有一个将执行的其他一些程序,像这样一个进程包:
CREATE PACKAGE BODY pkg IS
CREATE PROCEDURE do
IS
BEGIN
other_pkg.other_proc;
other_pkg2.other_proc2;
other_pkg3.other_proc3;
END;
END;
有什么办法有程序的并行执行而不是串行?
编辑:
这是使用的正确方法DBMS_SCHEDULER
在这种情况下:
CREATE PACKAGE BODY pkg IS
CREATE PROCEDURE do
IS
BEGIN
DBMS_SCHEDULER.CREATE_JOB('job_other_pkg.other_proc', 'STORED_PROCEDURE', 'other_pkg.other_proc;');
DBMS_SCHEDULER.RUN_JOB('job_other_pkg.other_proc', FALSE);
-- ...
END;
END;
您可以使用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;
另一种解决方案是破解Oracle的SQL并行机制 。 见答案如何在不同的会话在PL / SQL中同时执行存储过程 。
它采用威廉·罗伯逊的绝佳解决方案并行PL / SQL启动 。
(与测试Oracle 10g
)