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