Что происходит, когда процедура, выполняемая JOB, не завершается, когда JOB должен выполнить ее снова?

Я хочу знать, что происходит, когда процедура выполняется через задание, и до его завершения наступает время, когда задание вызывает следующее выполнение процедуры. Вот задание, которое я создал:

DECLARE
  X NUMBER;
    BEGIN
      SYS.DBMS_JOB.SUBMIT
       (
          job        => x
         ,what       => 'BEGIN PKG_DISTRIBUIDOR_SCHEDULER.PRC_DISTRIBUYE_TRANSACCIONES(5000); END;'
         ,next_date  => to_date(sysdate,'dd/mm/yyyy hh24:mi:ss')
         ,interval   => 'SYSDATE+30/86400'
         ,no_parse   => FALSE
       );
       DBMS_OUTPUT.PUT_LINE('Job Number is: ' || to_char(x));   
       COMMIT;
   END;

Как видите, задание выполняется каждые 30 секунд. Итак, если моя процедура (PRC_DISTRIBUYE_TRANSACCIONES) задерживается более чем на 30 секунд, что в этом случае делает задание?


person Edgar Hernandez    schedule 22.05.2019    source источник
comment
Параметр NEXT_DATE имеет тип DATE, а функция SYSDATE возвращает данные типа DATE, поэтому вам не нужно использовать функцию TO_DATE. Вы можете получить ошибочные даты, используя to_date(sysdate,'dd/mm/yyyy hh24:mi:ss'), потому что Oracle сначала преобразует SYSDATE в текст, используя параметр базы данных NLS_DATE_FORMAT, который по умолчанию — DD-MON-RR.   -  person alvalongo    schedule 22.05.2019


Ответы (2)


Если вы используете (старые устаревшие) задания, то есть DBMS_JOB

Время начала следующего выполнения определяется по завершении текущих заданий. Если вы укажете интервал как SYSDATE+30/86400, это не означает: задание выполняется каждые 30 секунд.

Это означает: следующие задания начинаются через 30 секунд после завершения предыдущего задания.

Если вы используете задания планировщика, т.е. DBMS_SCHEDULER

Сразу после запуска задания оценивается repeat_interval (например, FREQ=SECONDLY;INTERVAL=30), чтобы определить следующее запланированное время выполнения задания. Хотя это может произойти во время выполнения задания, новый экземпляр задания не запустится, пока не завершится текущий. См. О настройке повтора Интервал

Таким образом, это означает: если задание длится более 30 секунд, новое задание начнется сразу после завершения предыдущего задания.

person Wernfried Domscheit    schedule 22.05.2019
comment
Большой! Спасибо, чувак, отличный ответ. Теперь, что, если из-за характера моего приложения я хочу, чтобы задание выполнялось сразу после завершения предыдущих выполнений. Я думаю, что нужно установить интервал в одну секунду, но есть ли лучший способ добиться этого? - person Edgar Hernandez; 22.05.2019
comment
Утверждение для DBMS_JOB, вероятно, не совсем правильное - я видел несколько заданий, которые запускаются каждые 30 секунд. Если работа завершена в течение этого периода, она работает нормально. - person Marmite Bomber; 23.05.2019
comment
@MarmiteBomber, возможно, интервал был TRUNC(SYSDATE, 'MI')+30/86400 - person Wernfried Domscheit; 23.05.2019
comment
Нет, только что протестировано с INTERVAL SYSDATE+5/86400, задание приостанавливается на 3 секунды, а общий период составляет ровно 5 секунд. Только когда работа занимает больше времени, чем интервал, вы выходите из синхронизации. - person Marmite Bomber; 23.05.2019
comment
@MarmiteBomber, это странно. Может быть, сон работает в фоновом режиме. - person Wernfried Domscheit; 23.05.2019
comment
Если вы хотите, чтобы задание запускалось сразу после завершения, я бы предпочел бесконечный LOOP внутри процедуры и запустить эту процедуру один раз. - person Wernfried Domscheit; 23.05.2019

Ничего не происходит!
Только когда анонимный блок PL/SQL внутри параметра what заканчивается, следующая дата рассчитывается в соответствии с параметром interval.

person alvalongo    schedule 22.05.2019