Как предотвратить повторный запуск бизнес-процесса при перепроведении документа в 1С?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

Часто в прикладных решениях 1С возникает задача инициализации бизнес-процесса по факту оформления или проведения документа (например, запуск согласования заказа, процесса закупки или доставки). Если разместить программный код создания и старта бизнес-процесса непосредственно в обработчике проведения без дополнительных проверок, то при каждом повторном проведении документа платформа будет создавать и запускать новый экземпляр процесса. Это приводит к дублированию задач у исполнителей и засорению информационной базы.

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

Архитектурные риски старта бизнес-процесса в транзакции проведения

Прежде чем перейти к коду проверки, проанализируем, почему запуск бизнес-процесса внутри процедуры ОбработкаПроведения несет в себе серьезные риски:

  1. Длительные транзакции и блокировки данных: Процедура ОбработкаПроведения выполняется внутри транзакции записи. Вызов метода Старт() бизнес-процесса приводит к продвижению по карте маршрута, генерации задач (объекты Задача) и выполнению связанных с ними обработчиков. Это удлиняет транзакцию проведения и может вызывать взаимные блокировки при многопользовательской работе.
  2. Групповое перепроведение документов: При восстановлении последовательностей, закрытии месяца или групповом перепроведении документов запуск в проведении приведет к неконтролируемому массовому старту бизнес-процессов.
  3. Неотменяемые внешние действия: Если в точках маршрута бизнес-процесса настроена отправка электронных писем, SMS или запросов во внешние API, то в случае сбоя или установки Отказ = Истина в транзакции проведения документ останется непроведенным, а внешние уведомления уже уйдут получателям.

Способ 1. Проверка наличия бизнес-процесса перед созданием

Если в рамках дипломного проекта или простой конфигурации старт процесса все же реализован в модуле документа, добавим проверку существования связанного бизнес-процесса с помощью запроса. Рассмотрим пример:


Если ОбменДанными.Загрузка Тогда
    Возврат;
КонецЕсли;

// Проверяем, не был ли процесс уже запущен ранее
Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ ПЕРВЫЕ 1
    |	БизнесПроцесс.Ссылка КАК Ссылка
    |ИЗ
    |	БизнесПроцесс.БизнесПроцесс КАК БизнесПроцесс
    |ГДЕ
    |	БизнесПроцесс.Заказ = &Заказ
    |	И НЕ БизнесПроцесс.ПометкаУдаления";

Запрос.УстановитьПараметр("Заказ", ЭтотОбъект.Ссылка);

РезультатЗапроса = Запрос.Выполнить();

Если РезультатЗапроса.Пустой() Тогда
    // Процесс еще не создавался — создаем и стартуем
    НовыйБП = БизнесПроцессы.БизнесПроцесс.СоздатьБизнесПроцесс();
    НовыйБП.Дата = ЭтотОбъект.Дата;
    НовыйБП.Заказ = ЭтотОбъект.Ссылка;
    НовыйБП.Записать();
    НовыйБП.Старт();
КонецЕсли;

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

Способ 2. Проверка первичного проведения документа

Дополнительно выясним, проводится ли документ впервые или выполняется повторное проведение. Для этого сравним текущее состояние с состоянием документа в базе данных через ЭтотОбъект.Ссылка.Проведен:


// Если документ уже был проведен ранее, пропускаем запуск процесса
Если ЭтотОбъект.Ссылка.Проведен Тогда
    Возврат;
КонецЕсли;

// Также проверяем режим проведения: не запускаем при неоперативном проведении
Если РежимПроведения <> РежимПроведенияДокумента.Оперативный Тогда
    Возврат;
КонецЕсли;

Обратим внимание: если объект записывается впервые, свойство Ссылка.Проведен вернет Ложь. Если документ перепроводится, то в базе данных он уже имеет признак Проведен = Истина, что позволяет сразу отсечь повторные запуски без обращения к тяжелым процедурам.

Способ 3. Вынос запуска бизнес-процесса за пределы транзакции

Рассмотрим более надежное архитектурное решение: запуск бизнес-процесса после фиксации транзакции записи или по отдельной интерактивной команде пользователя.

  1. Запуск из формы документа: В форме документа в клиентском событии ПослеЗаписи(ПараметрыЗаписи) вызывается серверная процедура, которая создает и стартует процесс. В этот момент сам документ уже гарантированно записан и проведен в базе данных, а транзакция закрыта.
  2. Использование фоновых заданий: При проведении документа в специальный регистр сведений записывается признак необходимости обработки. Регламентное задание в фоновом режиме считывает очередь и стартует бизнес-процессы асинхронно, не задерживая работу пользователя.
  3. Хранение ссылки на процесс: В документ добавляется реквизит БизнесПроцесс. При первом запуске ссылка на созданный процесс записывается в этот реквизит, что делает проверку тривиальной и быстрой.

Использование проверки существующих процессов по реквизиту-основанию вместе с контролем первичного проведения позволяет полностью исключить дублирование задач и обеспечить стабильную работу системы.

← На главную