Почему регламентное задание 1С запускается повторно и как исправить расписание с переходом через полночь?

Программист IT и автоматизация бизнеса
← На главную

В процессе администрирования и разработки в 1С нередко возникает ситуация, когда фоновое регламентное задание, настроенное на однократный запуск в сутки, отрабатывает успешно, но затем неожиданно стартует второй раз. Особенно часто такое поведение проявляется у длительных ночных заданий (например, выгрузка каталогов, обмен данными, пересчет итогов). Разберем причины такого поведения встроенного планировщика 1С и выясним, как правильно настроить расписание и программный код для предотвращения дублирующих запусков.

Анализ механизма работы встроенного планировщика 1С

Рассмотрим, как планировщик регламентных заданий 1С интерпретирует настройки времени. В объекте РасписаниеРегламентногоЗадания параметры времени (время начала и время окончания) жестко привязаны к границам одних календарных суток — от 00:00:00 до 23:59:59.

Если в параметрах расписания указано, например: «каждый день; с 21:30:00 по 06:00:00 один раз в день», платформа делит этот период на два независимых временных интервала в рамках каждых астрономических суток:

  1. Интервал с 00:00:00 до 06:00:00 (утреннее окно текущего дня);
  2. Интервал с 21:30:00 до 23:59:59 (вечернее окно текущего дня).

Проанализируем хронологию событий, которая приводит к повторному запуску:

  1. В 21:30 первого дня регламентное задание успешно запускается по вечернему расписанию.
  2. Задание выполняется несколько часов и завершает работу после полуночи (например, в 04:30).
  3. В момент наступления 00:00:00 календарные сутки сменились. Для наступившего дня счетчик количества выполнений обнуляется («в эти сутки задание еще не выполнялось»).
  4. Текущее время завершения (04:30) попадает в разрешенный утренний интервал (с 00:00:00 по 06:00:00).
  5. Планировщик фиксирует наступление условий для запуска задания уже за новые сутки и немедленно инициирует повторный запуск.

Способ 1. Корректировка расписания регламентного задания

Самое простое и правильное решение — исключить интервалы, пересекающие границу суток, и убрать ограничение времени окончания, если в нем нет технологической необходимости.

Разберем по шагам, как задать корректные параметры:

  1. Открываем свойства регламентного задания в конфигураторе или в пользовательской обработке управления заданиями.
  2. В поле Время начала указываем точное время старта: 21:30:00.
  3. Поле Время окончания оставляем пустым (00:00:00).
  4. В поле Период повтора внутри дня оставляем значение пустым либо задаем количество выполнений в день равным 1.
  5. Снимаем флаг Количество повторов при аварийном завершении или уменьшаем интервал повтора, чтобы исключить ложные запуски при системных сбоях.

При таких настройках регламентное задание стартует ровно один раз в 21:30, а после полуночи планировщик не будет пытаться запустить его снова до наступления 21:30 следующих суток.

Способ 2. Программный контроль повторного запуска (защита от повторов)

Если требуется гарантировать, что процедура не выполнится повторно даже при ошибках планировщика, сбросе кэша кластера или перезапуске служб сервера, добавим программную защиту. Для этого зафиксируем дату последнего успешного выполнения в регистре сведений или константе и будем проверять разницу во времени перед началом работы.

Посмотрим на пример реализации такой проверки в процедуре регламентного задания:


Процедура ВыполнитьНочнуюВыгрузку() Экспорт

    // Проверяем минимальный интервал между успешными запусками (например, 12 часов = 43200 секунд)
    ДатаПоследнегоЗапуска = Константы.ДатаПоследнейНочнойВыгрузки.Получить();
    МинимальныйИнтервал = 43200; 

    Если ЗначениеЗаполнено(ДатаПоследнегоЗапуска) И (ТекущаяДата() - ДатаПоследнегоЗапуска < МинимальныйИнтервал) Тогда
        ЗаписьЖурналаРегистрации(
            "РегламентныеЗадания.НочнаяВыгрузка",
            УровеньЖурналаРегистрации.Предупреждение,
            ,
            ,
            "Повторный запуск отменен: с момента прошлого запуска прошло менее 12 часов."
        );
        Возврат;
    КонецЕсли;

    Попытка
        // Основной алгоритм длительной выгрузки
        ВыполнитьВыгрузкуТоваров();

        // Фиксируем успешное завершение
        Константы.ДатаПоследнейНочнойВыгрузки.Установить(ТекущаяДата());
        
        ЗаписьЖурналаРегистрации(
            "РегламентныеЗадания.НочнаяВыгрузка",
            УровеньЖурналаРегистрации.Информация,
            ,
            ,
            "Ночная выгрузка успешно завершена."
        );
    Исключение
        ЗаписьЖурналаРегистрации(
            "РегламентныеЗадания.НочнаяВыгрузка",
            УровеньЖурналаРегистрации.Ошибка,
            ,
            ,
            "Ошибка при выполнении выгрузки: " + ОписаниеОшибки()
        );
        ВызватьИсключение;
    КонецПопытки;

КонецПроцедуры

Способ 3. Проверка на дублирование экземпляров заданий

Иногда повторные запуски вызваны наличием дубликатов регламентного задания в базе данных. Такое случается при программном создании заданий или после обновлений конфигурации.

Проверим наличие активных экземпляров задания с помощью программного кода:


ВыборкаЗаданий = РегламентныеЗадания.ПолучитьРегламентныеЗадания();
Для Каждого Задание Из ВыборкаЗаданий Цикл
    Если Задание.Имя = "НочнаяВыгрузкаТоваров" Тогда
        Сообщить("Найдено задание: " + Задание.УникальныйИдентификатор 
            + ", Использование: " + Задание.Использование 
            + ", Предопределенное: " + Задание.Предопределенное);
    КонецЕсли;
КонецЦикла;

Если в списке обнаружено несколько активных экземпляров с одинаковым методом, необходимо отключить или удалить лишние непредопределенные копии.

Способ 4. Использование свойства «Ключ» для защиты от параллельного исполнения

Для предотвращения одновременного запуска двух копий одного и того же фонового задания рекомендуется задавать свойство Ключ у объекта регламентного задания. Если фоновое задание с указанным ключом уже выполняется, платформа 1С не запустит второй фоновый процесс, пока первый не завершит работу.


Задание = РегламентныеЗадания.НайтиПоУникальномуИдентификатору(ИдентификаторЗадания);
Если Задание <> Неопределено Тогда
    Задание.Ключ = "УникальныйКлючНочнойВыгрузки";
    Задание.Записать();
КонецЕсли;

Применение правильной настройки суточного расписания в сочетании с контролем времени последнего запуска позволяет полностью устранить ложные повторные срабатывания фоновых процессов в 1С.

← На главную