Oracle Scheduler作业无法每秒执行,求可行配置方案
解决Oracle Scheduler每秒执行作业的问题
你遇到的这个情况其实是Oracle Scheduler的默认行为限制——哪怕你把repeat_interval设为Freq=Secondly;Interval=1,作业协调器(Job Coordinator)的默认轮询间隔大概是3-4秒,它不会每秒都扫描待执行的作业,所以实际执行间隔会被拉长。下面给你几个可行的解决方案:
方法1:手动触发下一次执行,替代自动重复逻辑
放弃依赖repeat_interval的自动重复,改为在作业执行的末尾手动设置下一次运行时间,这样能保证作业完成后立刻调度下一次,更接近每秒执行的效果。
针对存储过程版本
修改你的存储过程proc_insert_data,在最后添加手动调度逻辑:
BEGIN sys.dbms_scheduler.set_attribute( job_name => 'WBC6_PUBLIC.TESTE', attribute => 'next_run_date', value => SYSDATE + 1/86400 -- 计算1秒后的时间 ); END;
然后创建作业时,把repeat_interval设为NULL:
begin sys.dbms_scheduler.create_job( job_name => 'WBC6_PUBLIC.TESTE', job_type => 'STORED_PROCEDURE', job_action => 'proc_insert_data', start_date => to_date('19-02-2020 09:00:00', 'dd-mm-yyyy hh24:mi:ss'), repeat_interval => NULL, -- 取消自动重复逻辑 end_date => to_date(null), job_class => 'DEFAULT_JOB_CLASS', enabled => true, auto_drop => false, comments => '每秒执行的作业,手动触发下一次运行'); end; /
针对PLSQL_BLOCK版本
直接把调度逻辑写到执行块里:
begin sys.dbms_scheduler.create_job( job_name => 'WBC6_PUBLIC.TESTE', job_type => 'PLSQL_BLOCK', job_action => ' insert into my_table (date) values (sysdate); BEGIN sys.dbms_scheduler.set_attribute( job_name => ''WBC6_PUBLIC.TESTE'', attribute => ''next_run_date'', value => SYSDATE + 1/86400 ); END;', start_date => to_date('19-02-2020 09:00:00', 'dd-mm-yyyy hh24:mi:ss'), repeat_interval => NULL, end_date => to_date(null), job_class => 'DEFAULT_JOB_CLASS', enabled => true, auto_drop => false, comments => '每秒执行的作业,手动触发下一次运行'); end; /
方法2:调整Oracle隐含参数(谨慎使用)
Oracle有个隐含参数_job_queue_interval,它控制作业协调器轮询待执行作业的间隔,默认值是4秒。你可以把它改成1秒,但要注意:
- 这是隐含参数,Oracle官方不建议随意修改,可能会增加数据库负载,尤其是作业较多的场景。
- 修改后需要重启数据库才能生效。
修改命令:
ALTER SYSTEM SET "_job_queue_interval" = 1 SCOPE=SPFILE;
重启数据库后,再创建你最初的作业,就能接近每秒执行的效果了。
额外注意事项
- 每秒执行的作业会持续消耗数据库资源,要确认业务真的需要这么高频的执行,同时监控CPU、IO等负载情况。
- 如果作业本身的执行时间超过1秒,那即使设置了每秒调度,实际执行间隔也会等于作业的执行时长,这点要提前评估。
内容的提问来源于stack exchange,提问作者dmoitim
相关产品推荐
相关产品推荐

