При администрировании и разработке в среде 1С:Предприятие 8.3 специалисты иногда сталкиваются с аномальным поведением планировщика задач. Типичный сценарий: после обновления платформы или переноса базы данных на другой сервер регламентное задание начинает выполняться параллельно в двух или более сеансах. При этом в стандартном интерфейсе администрирования (например, в консоли регламентных заданий БСП) отображается только одна запись, а в журнале регистрации фиксируются параллельные запуски, зачастую под разными пользователями. Рассмотрим причины возникновения этой проблемы, методы её диагностики и эффективные способы устранения.
Для того чтобы понять природу этого сбоя, проанализируем внутренние механизмы работы платформы 1С и СУБД. Когда регламентное задание настраивается в информационной базе, данные о его расписании, активности и параметрах запуска сохраняются в системных таблицах базы данных. В СУБД Microsoft SQL Server или PostgreSQL за хранение этих настроек отвечает специализированная таблица с именем ScheduledJobs (или аналогичная таблица метаданных в зависимости от версии платформы).
Сбой синхронизации происходит по следующим причинам:
UUID задания, из-за чего в форме отображается только одна строка. Однако низкоуровневый планировщик кластера серверов 1С считывает физическую таблицу напрямую и запускает каждый найденный поток независимо.DefUser или пустой пользователь), что приводит к созданию документов с неожиданным автором или к странным записям в журнале регистрации.Дополнительным фактором выступает серверное кэширование. Планировщик кластера серверов 1С кэширует информацию о расписаниях в файлах внутри каталога srvinfo (в частности, в служебных файлах snccntry.db и snccntry.lst). При некорректном обновлении платформы старый кэш может остаться активным, заставляя планировщик инициировать параллельный старт задачи.
Разберем по шагам, как диагностировать и решить эту проблему различными методами.
Самый простой и действенный способ, который помогает в большинстве случаев, — это полное удаление элемента планировщика и его последующее добавление. Рассмотрим этот алгоритм подробнее:
ScheduledJobs, удалив как видимый экземпляр, так и его скрытую "фантомную" копию, связанную тем же метаданным признаком.Этот метод отлично подходит для пользовательских регламентных заданий. Однако, если задание является предопределенным, платформа может не позволить удалить его интерактивно. В таком случае перейдем к альтернативным методам.
Если проблемное задание создано на уровне метаданных в конфигураторе как предопределенное, то просто удалить его кнопкой в консоли не получится. Нам потребуется написать небольшую внешнюю обработку или запустить скрипт в консоли кода. Проанализируем пример кода, который снимает признак предопределенности и полностью очищает дубли из базы:
// Определим структуру отбора по имени метаданных нашего регламентного задания
Отбор = Новый Структура("Метаданные", Метаданные.РегламентныеЗадания.ИмяВашегоЗадания);
НайденныеЗадания = РегламентныеЗадания.ПолучитьРегламентныеЗадания(Отбор);
Для Каждого ТекущееЗадание Из НайденныеЗадания Цикл
Попытка
// Сбрасываем признак предопределенности для корректного удаления
Если ТекущееЗадание.Предопределенное Тогда
ТекущееЗадание.Предопределенное = Ложь;
ТекущееЗадание.Записать();
КонецЕсли;
// Полностью удаляем задание из базы данных
ТекущееЗадание.Удалить();
ЗаписьЖурналаРегистрации("Администрирование.РегламентныеЗадания",
УровеньЖурналаРегистрации.Информация, , ,
"Успешно удалено задание: " + ТекущееЗадание.Наименование);
Исключение
ЗаписьЖурналаРегистрации("Администрирование.РегламентныеЗадания",
УровеньЖурналаРегистрации.Ошибка, , ,
"Ошибка удаления задания: " + ОписаниеОшибки());
КонецПопытки;
КонецЦикла;
После выполнения данного скрипта база данных будет полностью очищена от всех экземпляров этого регламентного задания. При следующем запуске сеанса или обновлении конфигурации платформа автоматически создаст ровно один чистый экземпляр предопределенного задания, который будет работать стабильно.
Если проблема вызвана некорректной работой службы кэширования кластера серверов, нам необходимо произвести сброс файлов планировщика. Выполним следующие шаги:
1C:Enterprise 8.3 Server Agent) через утилиту управления службами операционной системы.C:\Program Files\1cv8\srvinfo\ (для ОС Windows) или /home/usr1cv8/.1cv8/ (для ОС Linux).reg_1541), а внутри нее — каталог с идентификатором нашей информационной базы.snccntry.db и snccntry.lst.snc, ggr и временные файлы).При запуске сервер 1С заново считает актуальные данные из СУБД и сформирует файлы snccntry.db в консистентном состоянии, что исключит дублирование запусков на уровне кэша.
Рассмотрим превентивный метод защиты, который часто применяют разработчики программных решений на платформе 1С. Чтобы гарантировать, что фоновое задание никогда не запустится параллельно во втором экземпляре (даже при возникновении платформенных сбоев или ошибок СУБД), мы можем использовать свойство Ключ (Key) регламентного задания.
Платформа 1С:Предприятие на уровне ядра контролирует уникальность запускаемых фоновых заданий по их ключу. Если в момент старта задания система обнаруживает, что в кластере уже выполняется фоновое задание с точно таким же значением свойства Ключ, запуск второго экземпляра блокируется.
Мы можем установить это свойство программно при инициализации задания или при его изменении:
Отбор = Новый Структура("Метаданные", Метаданные.РегламентныеЗадания.ИмяВашегоЗадания);
НайденныеЗадания = РегламентныеЗадания.ПолучитьРегламентныеЗадания(Отбор);
Для Каждого ТекущееЗадание Из НайденныеЗадания Цикл
// Задаем уникальный ключ для защиты от параллельного запуска
Если ТекущееЗадание.Ключ <> "УникальныйКлючЗадания_ОбменДанными" Тогда
ТекущееЗадание.Ключ = "УникальныйКлючЗадания_ОбменДанными";
ТекущееЗадание.Записать();
КонецЕсли;
КонецЦикла;
Использование свойства Ключ — это отличный способ подстраховать критически важные операции (например, проведение документов, закрытие месяца или синхронизацию данных) от повторного и параллельного выполнения, которое может нарушить логику бизнес-процессов.