Oracle DBMS_SCHEDULER每分钟执行作业为何仅运行一次
问题根因
你的作业仅执行一次,核心是两个配置疏漏:
- 未显式关闭作业的自动删除属性:
DBMS_SCHEDULER.CREATE_JOB的默认参数中AUTO_DROP值为TRUE,当作业调度计算出现异常、或者Oracle判定调度无后续执行节点时,会自动删除作业,表现为仅运行一次就消失。 START_DATE与重复间隔的匹配问题:你传入的是创建时刻的systimestamp,这个时间戳的秒数是随机的,和你指定的BYSECOND=0规则匹配时,第一次运行完成后计算下一次执行时间容易出现逻辑偏移,无法生成有效的后续执行计划。
另外你写的逐行游标循环更新逻辑效率很低,会不必要地拉长事务持锁时间,完全可以用单条批量UPDATE替代。
修正方案
- 显式设置
AUTO_DROP => FALSE,避免作业被自动清理 - 把
START_DATE截断到最近的整分钟,和BYSECOND=0的间隔规则对齐,保证后续执行时间计算正确 - 替换逐行更新逻辑为批量更新,提升执行效率
修正后的创建脚本如下:
BEGIN DBMS_SCHEDULER.CREATE_JOB( JOB_NAME => 'DBMS_JOB_RESYNC_REQUESTS', JOB_TYPE => 'PLSQL_BLOCK', JOB_ACTION => ' BEGIN -- 直接批量更新符合条件的记录,无需游标循环 UPDATE TABLE1 SET STATUS = 3, LAST_UPDATED_DATE = SYSDATE WHERE STATUS = 2; COMMIT; END;', START_DATE => TRUNC(systimestamp, 'MI'), -- 截断到整分钟,和间隔规则对齐 REPEAT_INTERVAL => 'FREQ=MINUTELY;INTERVAL=1;BYSECOND=0;', END_DATE => NULL, ENABLED => TRUE, AUTO_DROP => FALSE, -- 关闭作业自动删除 COMMENTS => 'TESTING JOB'); END; /
排查验证方法
如果配置后仍有异常,可以执行以下SQL排查作业状态:
- 查看作业当前配置、下次执行时间:
SELECT JOB_NAME, NEXT_RUN_DATE, ENABLED, AUTO_DROP, STATE FROM USER_SCHEDULER_JOBS WHERE JOB_NAME = 'DBMS_JOB_RESYNC_REQUESTS';
- 查看作业历史运行记录、报错信息:
SELECT JOB_NAME, ACTUAL_START_DATE, STATUS, ERROR# FROM USER_SCHEDULER_JOB_RUN_DETAILS WHERE JOB_NAME = 'DBMS_JOB_RESYNC_REQUESTS' ORDER BY ACTUAL_START_DATE DESC;
内容的提问来源于stack exchange,提问作者Moises Ahumada
相关产品推荐
相关产品推荐

