Почему возникают «битые» ссылки при создании документов в фоновых заданиях и как это исправить?

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

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

Суть проблемы: нарушение транзакционности

Разберем, почему текущая схема автора приводит к ошибкам. Когда срабатывает подписка ПриЗаписи, основная транзакция записи документа еще не завершена. В этот момент:

  1. Объект ЭлектронноеПисьмоВходящее еще не зафиксирован в базе данных (не совершен Commit).
  2. Фоновое задание, которое запускается из подписки, работает в отдельном сеансе. Оно пытается считать или использовать ссылку на объект, который в рамках основной транзакции еще «не существует» или недоступен для других сеансов.
  3. Если в процессе записи письма происходит ошибка (например, сработал отказ или возникла блокировка), транзакция откатывается. Ссылка, переданная в фоновое задание, становится «битой», так как сам документ так и не был создан, а фоновый процесс уже начал работу над несуществующим объектом.

Предлагаемое решение: использование регистра сведений как очереди

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

Шаг 1. Организация регистра сведений для очереди

Вместо вызова тяжелой логики в подписке, создадим непериодический независимый РегистрСведений с названием, например, ОчередьСозданияОбращений. Его структура должна быть минимальной:

Шаг 2. Запись факта в регистр

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


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

Шаг 3. Обработка очереди регламентным заданием

Теперь мы создаем отдельное РегламентноеЗадание, которое работает по расписанию (например, каждые 5 минут). Это задание будет выбирать записи из регистра, где Статус = КОбработке, и создавать документы ВходящееОбращение.

Преимущества такого подхода:

Рекомендации по оптимизации

При реализации данного механизма обратите внимание на следующие моменты:

  1. Масштабируемость: Если объем почты очень велик, можно настроить регламентное задание так, чтобы оно обрабатывало пакеты записей (например, по 100 штук за один запуск).
  2. Зачистка регистра: После успешного создания документа ВходящееОбращение, обновляйте статус в регистре или удаляйте запись, чтобы не перегружать таблицу регистра историческими данными.
  3. Параллельность: Использование регистра позволяет распараллелить процесс создания обращений. Вы можете запускать несколько фоновых заданий, которые будут выбирать разные порции записей из регистра для обработки, что значительно повысит пропускную способность системы.

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

← На главную