dbms_scheduler嵌套链无法控制步骤顺序,如何配置等待子链完成?
Oracle DBMS_SCHEDULER 嵌套链等待子链完成的原生解决方案
问题根因
你当前遇到的异常执行顺序,根源是步骤2的程序采用了异步提交子链作业的逻辑:创建并启用子链作业后就直接标记步骤完成,没有等待子链运行结束,因此主链直接进入步骤3,子链在后台异步执行。
原生支持方案
DBMS_SCHEDULER本身提供了两种原生的嵌套链同步等待机制,无需自行统计作业实例计数:
方案1:将子链定义为主链步骤的关联程序(推荐)
直接把子链作为主链步骤的执行对象,调度器会自动处理等待逻辑:
- 先将按分区加载的逻辑封装为独立的调度链对象,例如命名为
LOAD_ACC_PARTITION_CHAIN,完成子链内部的步骤、规则配置并启用。 - 创建指向该子链的程序对象,类型指定为
CHAIN:
BEGIN DBMS_SCHEDULER.CREATE_PROGRAM( PROGRAM_NAME => 'DWH.LOAD_ACC_PART_PROG', PROGRAM_TYPE => 'CHAIN', PROGRAM_ACTION => 'DWH.LOAD_ACC_PARTITION_CHAIN', ENABLED => TRUE ); END; /
- 修改主链
ACCOUNTS_CHAIN中INSERT_ACC步骤关联的程序,替换为上面新建的LOAD_ACC_PART_PROG即可。
调度器运行到该主链步骤时会自动启动子链,只有子链全部步骤执行成功后,才会标记主链该步骤完成,进入后续的RUN_FILL_CORE_ACC步骤,子链运行失败也会直接同步到主链步骤的状态。
方案2:同步调用子链作业
如果不想改动现有子链的创建逻辑,可以在步骤2的程序中用RUN_JOB的同步模式执行子链作业,将WAIT参数设为TRUE,当前程序会阻塞直到子链作业运行结束:
BEGIN -- 原有创建子链作业LOAD_ACC_DB的逻辑 DBMS_SCHEDULER.CREATE_JOB( JOB_NAME => 'DWH.LOAD_ACC_DB', -- 其他作业配置参数 ENABLED => FALSE ); -- 同步运行子链作业,等待执行完成后再继续 DBMS_SCHEDULER.RUN_JOB( JOB_NAME => 'DWH.LOAD_ACC_DB', WAIT => TRUE ); END; /
该模式下子链作业的运行结果会直接返回给当前程序,运行异常会抛出对应错误,主链步骤会自动根据执行结果更新状态。
效果验证
修改后查看调度日志,INSERT_ACC步骤的成功时间会和LOAD_ACC_DB作业的成功时间一致,后续RUN_FILL_CORE_ACC步骤会在LOAD_ACC_DB所有子步骤完成后才启动,符合预期执行顺序。
内容的提问来源于stack exchange,提问作者Sherzodbek
相关产品推荐
相关产品推荐

