并行化PL/SQL中的调用

Mat*_*sen 5 oracle plsql oracle10g

我有一个包含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;
Run Code Online (Sandbox Code Playgroud)

有没有办法让程序并行而不是串行执行?

编辑:

这是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;
Run Code Online (Sandbox Code Playgroud)

Jus*_*ave 7

您可以使用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;
Run Code Online (Sandbox Code Playgroud)

如果您正在使用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;
Run Code Online (Sandbox Code Playgroud)