在 PL/SQL 中并行化调用

Parallelizing calls in PL/SQL(在 PL/SQL 中并行化调用)
本文介绍了在 PL/SQL 中并行化调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a package with a proc that will execute a number of other procedures, like so:

CREATE PACKAGE BODY pkg IS
    CREATE PROCEDURE do
    IS
    BEGIN
        other_pkg.other_proc;
        other_pkg2.other_proc2;
        other_pkg3.other_proc3;
    END;
END;

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

Is there any way to have the procedures execute in parallel rather than serially?

这是在这种情况下使用 DBMS_SCHEDULER 的正确方法吗:

Is this the proper way to use DBMS_SCHEDULER in this instance:

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,提交作业将成为事务的一部分,因此一旦事务完成,作业就会开始.

You can use the dbms_job (or dbms_scheduler) package to submit jobs that will run in parallel. If you are using dbms_job, submitting the jobs will be part of the transaction so the jobs will start once the transaction completes.

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 创建一个运行作业以响应某些其他操作或事件(例如将消息放入队列)的链).

If you are using dbms_scheduler, creating a new job is not transactional (i.e. there would be implicit commits each time you created a new job) which may cause problems with transactional integrity if there is other work being done in the transaction where this procedure is called. On the other hand, if you are using dbms_scheduler, it may be easier to create the jobs in advance and simply run them from the procedure (or to use dbms_scheduler to create a chain that runs the job in response to some other action or event such as putting a message on a queue).

当然,无论采用哪种解决方案,您都需要构建基础设施来监控这三个作业的进度,前提是您关心它们何时以及是否成功(以及它们是否会产生错误).

Of course, with either solution, you'd need to then build the infrastructure to monitor the progress of these three jobs assuming that you care when and whether they succeed (and whether they generate errors).

如果您打算使用 DBMS_SCHEDULER

  • 无需使用动态 SQL.您可以放弃 EXECUTE IMMEDIATE 而直接调用 DBMS_SCHEDULER 包的过程,就像调用任何其他过程一样.
  • 调用RUN_JOB时,需要传入第二个参数.use_current_session 参数控制作业是在当前会话中运行(并阻止)还是在单独的会话中运行(在这种情况下,当前会话可以继续并做其他事情).由于要并行运行多个作业,因此需要传入 false 值.
  • 虽然不是必需的,但更传统的做法是创建作业一次(将 auto_drop 设置为 false),然后从您的过程中运行它们.
  • There is no need to use dynamic SQL. You can ditch the EXECUTE IMMEDIATE and just call the DBMS_SCHEDULER package's procedures directly just like you would any other procedure.
  • When you call RUN_JOB, you need to pass in a second parameter. The use_current_session parameter controls whether the job runs in the current session (and blocks) or whether it runs in a separate session (in which case the current session can continue on and do other things). Since you want to run multiple jobs in parallel, you would need to pass in a value of false.
  • Although it is not required, it would be more conventional to create the jobs once (with auto_drop set to false) and then just run them from your procedure.

所以你可能想在包外创建作业,然后你的程序就会变成

So you would probably want to create the jobs outside the package and then your procedure would just become

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;

这篇关于在 PL/SQL 中并行化调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

SQL to Generate Periodic Snapshots from Transactions Table(用于从事务表生成定期快照的SQL)
MyBatis support for multiple databases(MyBatis支持多个数据库)
Oracle 12c SQL: Missing column Headers in result(Oracle 12c SQL:结果中缺少列标题)
SQL query to find the number of customers who shopped for 3 consecutive days in month of January 2020(查询2020年1月连续购物3天的客户数量)
How to get top 10 data weekly (This week, Previous week, Last month, 2 months ago, 3 month ago)(如何每周获取前十大数据(本周、前一周、上个月、2个月前、3个月前))
Select the latest record for an Id per day - Oracle pl sql(选择每天ID的最新记录-Oracle pl SQL)