Как реализовать фоновое выполнение кода после проведения документа в 1С, чтобы не блокировать работу пользователя?

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

При работе в высоконагруженных системах, таких как 1С:Комплексная автоматизация 2.5 или 1С:ERP, часто возникает необходимость выполнить тяжелые операции сразу после того, как документ был проведен. Это может быть выгрузка данных на сайт, формирование дополнительных записей в справочниках или рассылка уведомлений. Если выполнять эти действия в основной транзакции проведения, пользователь будет вынужден ждать завершения всех процессов, что негативно сказывается на производительности и комфорте работы. Разберем, как правильно вынести такие задачи в «фон».

Вариант 1. Использование регистра-очереди заданий (Паттерн Transactional Outbox)

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

Рассмотрим по шагам, как это реализовать:

  1. Создадим РегистрСведений, например, ОчередьЗаданийКВыполнению. В качестве измерений укажем Объект (ЛюбаяСсылка), а в ресурсах — ДатаДобавления, КоличествоПопыток и Статус (Перечисление: Новое, ВРаботе, Ошибка).
  2. В модуле объекта документа, в процедуре ОбработкаПроведения, добавим код для записи в этот регистр. Важный момент: запись должна происходить внутри транзакции проведения. Если проведение документа сорвется, запись в очереди также будет отменена, что гарантирует согласованность данных.

Пример кода в модуле документа:


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

Затем создадим РегламентноеЗадание, которое будет раз в минуту считывать записи из регистра и выполнять целевой код. После успешного выполнения запись из регистра следует удалить или пометить как выполненную.

Вариант 2. Использование подсистемы БСП «Длительные операции»

Если нам нужно запустить фоновое выполнение сразу после нажатия кнопки пользователем (из формы), мы можем воспользоваться программным интерфейсом Библиотеки стандартных подсистем (БСП). Метод ВыполнитьВФоне из общего модуля ДлительныеОперации позволяет запустить серверную процедуру асинхронно.

Проанализируем ситуацию: пользователь нажимает «Провести и закрыть». Нам нужно, чтобы форма закрылась, а процесс пошел. В модуле формы документа можно использовать следующий подход:


&НаКлиенте
Процедура ПослеЗаписи(ПараметрыЗаписи)
    Если ПараметрыЗаписи.РежимЗаписи = РежимЗаписиДокумента.Проведение Тогда
        ПараметрыВыполнения = Новый Структура("Ссылка", Объект.Ссылка);
        // Запуск фонового задания через БСП
        ДлительныеОперации.ВыполнитьВФоне("МойОбщийМодуль.ВыполнитьИнтеграциюССайтом", ПараметрыВыполнения);
    КонецЕсли;
КонецПроцедуры

Выясним преимущество этого метода: он прост в реализации и не требует создания дополнительных объектов метаданных. Однако стоит помнить, что при падении сервера 1С или рабочего процесса rphost такое задание может просто исчезнуть без возможности повтора, в отличие от варианта с регистром-очередью.

Вариант 3. Интеграция в механизм «Отложенного проведения» КА 2.5

В конфигурациях 1С:Комплексная автоматизация и 1С:ERP уже существует мощный механизм отложенного формирования движений. Мы можем рассмотреть возможность внедрения своего кода в этот штатный процесс. Например, можно добавить обработчик в процедуру расчета себестоимости или отражения в регламентированном учете.

Разберем, почему это удобно: система сама управляет потоками фоновых заданий, мониторингом ошибок и повторными попытками. Это исключает «зоопарк» из множества самописных регламентных заданий и снижает нагрузку на систему лицензирования.

Важные архитектурные принципы

При выносе кода в фон крайне важно соблюдать три правила, о которых часто забывают разработчики:

  1. Идемпотентность кода. Выясним, что это значит: если фоновое задание запустится дважды по одному и тому же документу (например, из-за сбоя сети), оно не должно создать дублей на сайте или повторно изменить данные. Проверяйте наличие результата перед выполнением действия.
  2. Retry-логика (Повторы). Проанализируем ситуацию: внешний HTTP-сервис сайта временно недоступен. Фоновое задание должно уметь «засыпать» и повторять попытку через увеличивающиеся интервалы времени (5 минут, 15 минут, 1 час).
  3. Мониторинг. Кто узнает об ошибке? Рекомендуем записывать детальные логи в ЖурналРегистрации или специализированный регистр сведений, чтобы администратор мог оперативно увидеть причину сбоя (например, некорректно заполненные данные в документе, которые не принимает API сайта).

Когда все же стоит оставить код в транзакции?

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

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

← На главную