В процессе администрирования и разработки в 1С нередко возникает ситуация, когда фоновое регламентное задание, настроенное на однократный запуск в сутки, отрабатывает успешно, но затем неожиданно стартует второй раз. Особенно часто такое поведение проявляется у длительных ночных заданий (например, выгрузка каталогов, обмен данными, пересчет итогов). Разберем причины такого поведения встроенного планировщика 1С и выясним, как правильно настроить расписание и программный код для предотвращения дублирующих запусков.
Рассмотрим, как планировщик регламентных заданий 1С интерпретирует настройки времени. В объекте РасписаниеРегламентногоЗадания параметры времени (время начала и время окончания) жестко привязаны к границам одних календарных суток — от 00:00:00 до 23:59:59.
Если в параметрах расписания указано, например: «каждый день; с 21:30:00 по 06:00:00 один раз в день», платформа делит этот период на два независимых временных интервала в рамках каждых астрономических суток:
Проанализируем хронологию событий, которая приводит к повторному запуску:
Самое простое и правильное решение — исключить интервалы, пересекающие границу суток, и убрать ограничение времени окончания, если в нем нет технологической необходимости.
Разберем по шагам, как задать корректные параметры:
21:30:00.00:00:00).1.При таких настройках регламентное задание стартует ровно один раз в 21:30, а после полуночи планировщик не будет пытаться запустить его снова до наступления 21:30 следующих суток.
Если требуется гарантировать, что процедура не выполнится повторно даже при ошибках планировщика, сбросе кэша кластера или перезапуске служб сервера, добавим программную защиту. Для этого зафиксируем дату последнего успешного выполнения в регистре сведений или константе и будем проверять разницу во времени перед началом работы.
Посмотрим на пример реализации такой проверки в процедуре регламентного задания:
Процедура ВыполнитьНочнуюВыгрузку() Экспорт
// Проверяем минимальный интервал между успешными запусками (например, 12 часов = 43200 секунд)
ДатаПоследнегоЗапуска = Константы.ДатаПоследнейНочнойВыгрузки.Получить();
МинимальныйИнтервал = 43200;
Если ЗначениеЗаполнено(ДатаПоследнегоЗапуска) И (ТекущаяДата() - ДатаПоследнегоЗапуска < МинимальныйИнтервал) Тогда
ЗаписьЖурналаРегистрации(
"РегламентныеЗадания.НочнаяВыгрузка",
УровеньЖурналаРегистрации.Предупреждение,
,
,
"Повторный запуск отменен: с момента прошлого запуска прошло менее 12 часов."
);
Возврат;
КонецЕсли;
Попытка
// Основной алгоритм длительной выгрузки
ВыполнитьВыгрузкуТоваров();
// Фиксируем успешное завершение
Константы.ДатаПоследнейНочнойВыгрузки.Установить(ТекущаяДата());
ЗаписьЖурналаРегистрации(
"РегламентныеЗадания.НочнаяВыгрузка",
УровеньЖурналаРегистрации.Информация,
,
,
"Ночная выгрузка успешно завершена."
);
Исключение
ЗаписьЖурналаРегистрации(
"РегламентныеЗадания.НочнаяВыгрузка",
УровеньЖурналаРегистрации.Ошибка,
,
,
"Ошибка при выполнении выгрузки: " + ОписаниеОшибки()
);
ВызватьИсключение;
КонецПопытки;
КонецПроцедуры
Иногда повторные запуски вызваны наличием дубликатов регламентного задания в базе данных. Такое случается при программном создании заданий или после обновлений конфигурации.
Проверим наличие активных экземпляров задания с помощью программного кода:
ВыборкаЗаданий = РегламентныеЗадания.ПолучитьРегламентныеЗадания();
Для Каждого Задание Из ВыборкаЗаданий Цикл
Если Задание.Имя = "НочнаяВыгрузкаТоваров" Тогда
Сообщить("Найдено задание: " + Задание.УникальныйИдентификатор
+ ", Использование: " + Задание.Использование
+ ", Предопределенное: " + Задание.Предопределенное);
КонецЕсли;
КонецЦикла;
Если в списке обнаружено несколько активных экземпляров с одинаковым методом, необходимо отключить или удалить лишние непредопределенные копии.
Для предотвращения одновременного запуска двух копий одного и того же фонового задания рекомендуется задавать свойство Ключ у объекта регламентного задания. Если фоновое задание с указанным ключом уже выполняется, платформа 1С не запустит второй фоновый процесс, пока первый не завершит работу.
Задание = РегламентныеЗадания.НайтиПоУникальномуИдентификатору(ИдентификаторЗадания);
Если Задание <> Неопределено Тогда
Задание.Ключ = "УникальныйКлючНочнойВыгрузки";
Задание.Записать();
КонецЕсли;
Применение правильной настройки суточного расписания в сочетании с контролем времени последнего запуска позволяет полностью устранить ложные повторные срабатывания фоновых процессов в 1С.