네이버 지식인에 DBMS_JOB으로 만들어진 JOB의 interval을 1초로 지정해도 
5초 정도의 interval을 갖는다는 질문이 있어 간단히 테스트 해 봤습니다. 

DBMS_JOB package로 job을 생성합니다 
SQL> variable jobno number;
SQL> begin
SQL> dbms_job.submit(:jobno,'insert into test values (sysdate);',
SQL> sysdate,'sysdate+1/60/24/50',FALSE);
SQL> end;
SQL> /

PL/SQL procedure successfully completed.

SQL> print jobno
     JOBNO
----------
        21

SQL> exec dbms_job.run(21);
PL/SQL procedure successfully completed.

SQL> commit;
Commit complete.

SQL> select * from user_jobs;

       JOB LOG_USER                       PRIV_USER                      SCHEMA_USER                    LAST_DATE LAST_SEC         THIS_DATE THIS_SEC         NEXT_DATE NEXT_SEC         TOTAL_TIME B
---------- ------------------------------ ------------------------------ ------------------------------ --------- ---------------- --------- ---------------- --------- ---------------- ---------- -
INTERVAL
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  FAILURES
----------
WHAT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
NLS_ENV
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
MISC_ENV                                                           INSTANCE
---------------------------------------------------------------- ----------
        21 SYS                            SYS                            SYS                            12-OCT-10 16:50:28                                    12-OCT-10 16:50:29                  0 N
sysdate+1/60/24/50
         0
insert into test values (sysdate);
NLS_LANGUAGE='AMERICAN' NLS_TERRITORY='AMERICA' NLS_CURRENCY='$' NLS_ISO_CURRENCY='AMERICA' NLS_NUMERIC_CHARACTERS='.,' NLS_DATE_FORMAT='DD-MON-RR' NLS_DATE_LANGUAGE='AMERICAN' NLS_SORT='BINARY'
0102000202000000                                                          0

JOB 내역을 보면 정상적으로 NEXT_DATE는 LAST_DATE + 1초로 나옵니다 

SQL> alter session set nls_date_format = 'YYYY/MM/DD HH24:MI:SS';
Session altered.

SQL> select * from test;
COMMIT_DATE
-------------------
2010/10/12 16:50:04
2010/10/12 16:50:08
2010/10/12 16:50:13
2010/10/12 16:50:18
2010/10/12 16:50:23
2010/10/12 16:50:28
2010/10/12 16:50:33
2010/10/12 16:50:38
2010/10/12 16:50:43
2010/10/12 16:50:48
2010/10/12 16:50:53
2010/10/12 16:50:58
2010/10/12 16:51:03
2010/10/12 16:51:08

14 rows selected.

그러나 table에 들어간 시간을 보니 4초 차이가 발생하는 군요...

SQL> exec dbms_job.broken(21,TRUE);
PL/SQL procedure successfully completed.

SQL> exec dbms_job.remove(21);
PL/SQL procedure successfully completed.

SQL> delete from test;
25 rows deleted.

SQL> commit;
Commit complete.

이번엔 DBMS_SCHEDULER로 테스트 해봤습니다. 

SQL> begin
  2  dbms_scheduler.create_schedule(
schedule_name  => 'INTERVAL_EVERY_1_SECONDS',
  start_date    => trunc(sysdate),
  repeat_interval => 'freq=SECONDLY;interval=1',
  comments     => 'Runtime: Every day all 1 SECONDS');  3    4    5    6  
  7  end;
  8  /

PL/SQL procedure successfully completed.

1초에 한번씩 수행할 Schedule을 생성합니다 

SQL> begin
dbms_scheduler.create_program
(program_name=> 'TEST_PROC01',
 program_type=> 'STORED_PROCEDURE',
 program_action=> 'SYS.TEST_PROC',
 enabled=>true,
 comments=>'job interval test'
 );
end;
PL/SQL procedure successfully completed.

수행할 Program을 생성합니다. 
TEST_PROC는 test table에 sysdate를 입력하는 procedure 입니다.

SQL> begin
dbms_scheduler.create_job
 (job_name => 'JOB_TEST',
  program_name=> 'TEST_PROC01',
  schedule_name=>'INTERVAL_EVERY_1_SECONDS',
  enabled=>true,
  auto_drop=>false,
  comments=>'job test');
end;
/  
PL/SQL procedure successfully completed.

이제 먼저 생성한 schedule과 program을 이용해 JOB을 생성합니다 

SQL> begin
dbms_scheduler.run_job('JOB_TEST',TRUE);
end; 
/
PL/SQL procedure successfully completed.



SQL> select * from test;

COMMIT_DATE
-------------------
2010/10/12 17:12:38
2010/10/12 17:12:39
2010/10/12 17:12:40
2010/10/12 17:12:41
2010/10/12 17:12:42
2010/10/12 17:12:43
2010/10/12 17:12:44
2010/10/12 17:12:45
2010/10/12 17:12:46
2010/10/12 17:12:47
2010/10/12 17:12:48
2010/10/12 17:12:49
2010/10/12 17:12:50
2010/10/12 17:12:51
2010/10/12 17:12:52
2010/10/12 17:12:53
2010/10/12 17:12:54
2010/10/12 17:12:55
2010/10/12 17:12:55
2010/10/12 17:12:56
2010/10/12 17:12:57
2010/10/12 17:12:58
2010/10/12 17:12:59
2010/10/12 17:13:00
2010/10/12 17:13:01
...

table에 들어간 데이터를 보니 1초에 한번씩 수행하고 있군요.. 

DBMS_JOB을 이용한 job은 interval에 제한이 있는 걸까요? 그런 자료는 못 본것 같은데..

예전 oracle 8에서 job_queue_interval parameter가 있을때
수행 시간이 job_queue_interval 주기때문에 job interval이 정확히 계산되지 않았던 것 같은데... 
혹시 job_queue_process가 wake-up 하는 시간때문일까요?  





+ Recent posts