【问题标题】:oracle dbms_scheduler to run multiple procedures in paralleloracle dbms_scheduler 并行运行多个过程
【发布时间】:2013-08-14 13:39:35
【问题描述】:

我正在尝试找出 oracle 的 DBMS_SCHEDULER (Oracle 11g),需要帮助设置以下内容:

我有一个过程调用其他过程的列表,如下所示:

CREATE OR REPLACE
PROCEDURE RUN_JOBS AS
BEGIN
  MYUSER.MYPROCEDURE1();
  MYUSER.MYPROCEDURE2();
  MYUSER.MYPROCEDURE3();
  MYUSER.MYPROCEDURE4();
  MYUSER.MYPROCEDURE5();
END;
/

我想使用 DBMS_SCHEDULER 来运行 MYPROCEDURE3()、MYPROCEDURE4()、MYPROCEDURE5() 在 MYPROCEDURE2() 完成后并行

谁能告诉我如何设置的示例?

【问题讨论】:

    标签: oracle oracle11g job-scheduling dbms-scheduler


    【解决方案1】:

    可以参考DBMS_SCHEDULER包下的Chains:http://docs.oracle.com/cd/B28359_01/server.111/b28310/scheduse009.htm

    您也可以通过 Oracle Enterprise Manager 实现相同的目的,但我现在找不到任何文档链接。

    【讨论】:

      【解决方案2】:

      您可以使用 DBMS_SCHEDULER 做到这一点。

      CREATE OR REPLACE PROCEDURE RUN_JOBS
      AS
      v_JobNum NUMBER := 1;
      BEGIN
       BEGIN
        DBMS_JOB.SUBMIT(v_JobNum,'MYUSER.MYPROCEDURE1;',sysdate,'sysdate +1');
        DBMS_JOB.SUBMIT(v_JobNum,'MYUSER.MYPROCEDURE2;',sysdate,'sysdate +1');
        DBMS_JOB.SUBMIT(v_JobNum,'MYUSER.MYPROCEDURE3;',sysdate,'sysdate +1');
        DBMS_JOB.SUBMIT(v_JobNum,'MYUSER.MYPROCEDURE4;',sysdate,'sysdate +1');
        COMMIT;
       END;
      END RUN_JOBS; 
      /
      

      这将提交作业并立即运行它们。

      【讨论】:

        【解决方案3】:

        为每个程序创建三个不同的作业并同时安排它们。

        【讨论】:

        • 那行不通 - 在 Proc 2 完成后您将无法触发所有这些
        【解决方案4】:

        这是我将工作并行化为 N 个单独的作业的自定义方法,保留了 dbms_scheduler 的日志记录和背压支持。日期间隔由 mod N 传播。

        create table message_fixup_log (
            source_date date not null,
            started_at timestamp(6) not null,
            finished_at timestamp(6),
            fixed_message_count number(10)
        );
        alter table message_fixup_log add duration as (finished_at - started_at);
        create unique index ix_message_fixup_log_date on message_fixup_log(source_date desc);
        
        create or replace procedure message_fixup(jobNumber number, jobCount number, jobName varchar default null)
        is
            minSince date;
            maxSince date;
            since date;
            msgUpdatedCount number;
        begin
            -- choose interval
            select trunc(min(ts)) into minSince from message_part;
            select trunc(max(ts))+1 into maxSince from message_part;
            begin
                select max(source_date) + jobCount into since from message_fixup_log
                where finished_at is not null
                      and mod(source_date - minSince, jobCount) = jobNumber
                      and source_date >= minSince;
            exception when no_data_found then null;
            end;
            if (since is null) then
                since := minSince + jobNumber;
            end if;
            if (since >= maxSince) then
                if (jobName is not null) then
                    dbms_scheduler.set_attribute(jobName, 'end_date', systimestamp + interval '1' second);
                end if;
                return;
            end if;
        
            insert into message_fixup_log(source_date, started_at) values(since, systimestamp);
        
            -- perform some actual work for chosen interval
            msgUpdatedCount := sql%rowcount;
        
            update message_fixup_log
            set fixed_message_count = msgUpdatedCount, finished_at = systimestamp
            where source_date = since;
        end;
        
        -- manual test
        --call message_fixup(0, 1);
        
        declare
            jobName varchar2(256);
            jobCount number default 8;
        begin
            for jobNumber in 0..(jobCount-1) loop
                jobName := 'message_fixup_job' || jobNumber;
                begin
                    dbms_scheduler.drop_job(jobName, true);
                    exception
                    when others then null;
                end;
                dbms_scheduler.create_job(
                        job_name          => jobName,
                        job_type          =>  'stored_procedure',
                        job_action        =>  'message_fixup',
                        enabled           =>  false,
                        start_date        =>  systimestamp,
                        repeat_interval   =>  'freq = minutely; interval = 1',
                        number_of_arguments => 3
                );
                dbms_scheduler.set_attribute(jobName, 'logging_level', dbms_scheduler.logging_full);
                dbms_scheduler.set_job_anydata_value(jobName, 1, ANYDATA.ConvertNumber(jobNumber));
                dbms_scheduler.set_job_anydata_value(jobName, 2, ANYDATA.ConvertNumber(jobCount));
                dbms_scheduler.set_job_argument_value(jobName, 3, jobName);
                dbms_scheduler.enable(jobName);
            end loop;
        end;
        

        【讨论】:

          猜你喜欢
          • 2018-02-17
          • 2016-12-25
          • 2013-11-11
          • 2018-11-28
          • 2021-10-21
          • 2021-12-18
          • 2021-10-20
          • 2013-10-10
          • 1970-01-01
          相关资源
          最近更新 更多