5

我有一个带有 proc 的包,它将执行许多其他过程,如下所示:

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;
4

2 回答 2

7

您可以使用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;
于 2013-01-25T21:53:42.953 回答
1

Another solution is to hack Oracle's SQL parallelism mechanism. See answer to How to execute a stored procedure in a different session in same time in pl/sql .

It uses William Robertson's great solution Parallel PL/SQL launcher.

(tested with Oracle 10g)

于 2016-05-12T08:27:41.133 回答