При настройке регулярных механизмов обмена данными или длительных обработок документов в 1С часто возникает ситуация, когда очередное регламентное задание запускается по расписанию раньше, чем успевает завершиться предыдущий сеанс. Это приводит к конфликтам доступа при попытке одновременного редактирования и проведения одного и того же документа несколькими фоновыми процессами.
Рассмотрим подробно несколько проверенных способов решения этой проблемы: от простой настройки расписания платформы до написания управляющего программного кода.
Проанализируем ситуацию: стандартный интервал расписания задает строгое время запуска (например, каждые 20 минут). Если один из сеансов задерживается из-за проведения большого объема документов, планировщик 1С по умолчанию создаст новое фоновое задание. Оба процесса начнут работать параллельно и заблокируют доступ к общим данным.
Чтобы избежать этой коллизии, необходимо либо изменить логику работы самого расписания, либо задействовать механизмы платформы для отслеживания повторных запусков.
Самый простой и эффективный способ штатно решить проблему — изменить тип интервала в расписании регламентного задания. Вместо фиксированного времени старта укажем паузу между завершением и новым запуском.
ПаузаПовтора объекта РасписаниеРегламентногоЗадания).При такой настройке платформой отсчитывается указанный интервал времени только после завершения предыдущего сеанса. Если процедура обмена выполнялась дольше обычного, следующий старт автоматически сдвинется, и параллельный запуск станет невозможен.
Разберем штатный механизм защиты платформы 1С от дублирования фоновых процессов. У регламентных и фоновых заданий предусмотрено специальное строковое свойство Ключ.
Если у регламентного задания заполнен параметр Ключ, сервер кластера 1С перед запуском проверяет, существует ли уже активное фоновое задание с таким же именем метода и ключом:
Свойство Ключ можно задать как в конфигураторе в свойствах регламентного задания, так и программно при вызове метода ФоновыеЗадания.Выполнить().
Посмотрим на пример кода, если требуется явно отменить выполнение процедуры прямо в начале ее работы. Для этого запросим у сервера список действующих фоновых процессов и отменим повторное выполнение, если экземпляр уже активен.
Проанализируем следующий код, который помещается в самое начало процедуры регламентного задания:
Отбор = Новый Структура();
Отбор.Вставить("Наименование", "Автообмен");
Отбор.Вставить("Состояние", СостояниеФоновогоЗадания.Активно);
АктивныеЗадания = ФоновыеЗадания.ПолучитьФоновыеЗадания(Отбор);
Если АктивныеЗадания.Количество() > 1 Тогда
Возврат;
КонецЕсли;
В данном примере мы формируем структуру отбора по имени задания и его статусу СостояниеФоновогоЗадания.Активно. Метод ФоновыеЗадания.ПолучитьФоновыеЗадания() возвращает массив текущих выполняемых процессов. Если их число больше единицы (учитывая текущий запущенный сеанс), новый процесс мгновенно завершает свою работу через инструкцию Возврат.
Использование флагов в константах или справочниках не рекомендуется, так как при нештатном завершении фонового процесса (авария рабочего процесса rphost) флаг может остаться в состоянии блокировки («заклинить»).
Для надежной защиты выделим еще два архитектурных подхода:
БлокировкаДанных) на определенный элемент или узел обмена. Если задание аварийно завершится, платформа 1С автоматически снимет блокировку, и следующий запуск пройдет штатно.ДлительныеОперации.ЗаданиеВыполняется(Ключ), которая возвращает булево значение и позволяет легко проверить статус фонового процесса по его ключу.