概念描述

在晚间创建较大的定时任务时,总会有少许担忧怕定时任务执行的时间过长,而影响到次日白天业务的执行效率。比如,创建对某个大的分区表收集统计信息的任务,大的跑批任务等等。

这时就可以通过配置job的stop_on_window_close属性,让job在达到对应window设置duration后,随着window的关闭而终止。

测试验证

  1. 测试环境搭建
1.1 使用scott用户创建测试表t1:
conn scott/scott

create table t1 as select 'First record at: '||to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') as mycol from dual;

Table created.
1.2 创建定期执行的存储过程:

create or replace procedure testcase_for_aa is

v_ret_text clob;

begin
 insert into scott.t1 select 'Start at: '||to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') from dual;
 commit;
 dbms_lock.sleep(200);
 insert into scott.t1 select 'End at: '||to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') from dual;
 commit;
end;  

Procedure created.

注释:本存储过程是先插入一条当前时间的记录到测试表t1,停200秒,再插入一条结束时间的记录到测试表t1,也就是说存储过程正常执行下来需要3分钟20秒。

1.3 建立job和window:
a. 创建window
begin
  dbms_scheduler.create_window(window_name     => 'testcase_for_aa_window',
                               resource_plan   => null,
                               repeat_interval => 'freq=daily; byhour=22; byminute=52; bysecond=00',
                               duration        => interval '3' minute);
end;
/
注释:window要求开始的时间定为2023-09-10 22:52:00 PM, window设定的duration是3分钟。

b. 创建job
begin
  dbms_scheduler.create_job(job_name      => 'testjob_testcase_for_aa',
                            job_type      => 'stored_procedure',
                            job_action    => 'testcase_for_aa',
                            schedule_name => 'testcase_for_aa_window',
                            auto_drop     => false,
                            enabled       => true);
end;
/
注释:schedule_name 这里定时器的名字关联刚刚创建的window。
  1. 查看定时任务执行记录

注意:job执行了3分20秒钟,超过了window设置的duration20秒,也就是说job在window关闭后并未马上终止,而是完成了200秒的设定后才自行终止的。这个并不是我们想要结果。

查看t1内容:

定时任务Oracle dbms_scheduler之-stop_on_window_close属性_存储过程

注释:t1内关于job有完整的Start和End时间戳记录。

3. 设置job的’stop_on_window_close’属性

3.1 清理job:
begin
  dbms_scheduler.drop_job(job_name => 'TESTJOB_TESTCASE_FOR_AA');
end;
/
3.2 清理window
begin
  DBMS_SCHEDULER.drop_window(window_name => 'TESTCASE_FOR_AA_WINDOW');
end;
/
3.3 重新创建window和job
begin
  dbms_scheduler.create_window(window_name     => 'testcase_for_aa_window',
                               resource_plan   => null,
                               repeat_interval => 'freq=daily; byhour=23; byminute=00; bysecond=00',
                               duration        => interval '3' minute);
end;
/
begin
  dbms_scheduler.create_job(job_name      => 'testjob_testcase_for_aa',
                            job_type      => 'stored_procedure',
                            job_action    => 'testcase_for_aa',
                            schedule_name => 'testcase_for_aa_window',
                            auto_drop     => false,
                            enabled       => true);
end;
/
begin
  dbms_scheduler.set_attribute('TESTJOB_TESTCASE_FOR_AA',
                               'stop_on_window_close',
                               TRUE);
end;
/
注释:设置job TESTJOB_TESTCASE_FOR_AA的'stop_on_window_close'属性为TRUE,既window关闭时job自动终止。
  1. 再次查看定时任务执行记录

定时任务Oracle dbms_scheduler之-stop_on_window_close属性_时间戳_02


注释:当设置’stop_on_window_close’属性为TRUE后,发现job在执行了2分58秒后< windwo duration的设定时就结束了。查看t1内的记录:

定时任务Oracle dbms_scheduler之-stop_on_window_close属性_定时任务_03


注释:发现第二次执行时存储过程实际并没有执行完,因为t1里没有第二个“End at”时间戳!

知识总结

从实验中我们可以得出结论,在定时任务很可能会超出window定义的duration时,为了避免定时任务执行时间过长(影响到白天的正常业务),建议将job的’stop_on_window_close’属性设为TRUE。

参考文档

http://www.taodudu.cc/news/show-1245985.html