При интеграции между несколькими информационными базами 1С часто возникает типовая проблема: при проведении или интерактивной отправке документа запускается процесс передачи данных через внешнее подключение (например, V83.COMConnector), из-за чего сеанс пользователя блокируется и «зависает» до момента завершения отправки. Разберем, как правильно разделить процесс записи и проведения документа от передачи данных, чтобы пользователь мог продолжать комфортную работу без задержек.
Проанализируем, почему выгрузка в момент проведения или нажатия кнопки блокирует работу клиента. Установка COM-соединения требует инициализации отдельного процесса и сеанса в целевой базе, что само по себе занимает от нескольких секунд до десятков секунд. Если выполнять эту операцию непосредственно в клиентском коде или внутри серверной транзакции проведения, происходят следующие негативные эффекты:
ОбработкаПроведения модуля объекта, транзакция СУБД остается открытой на все время сетевого обмена. Это приводит к длительным блокировкам таблиц и ошибкам параллельной работы других пользователей.ФоновыеЗадания.Выполнить запускает отдельный сеанс. Если вызвать его до фиксации транзакции проведения, фоновый процесс не увидит еще не зафиксированные данные в СУБД либо натолкнется на блокировку чтения.Рассмотрим базовый вариант решения задачи с использованием механизма фоновых заданий платформы. Главное правило — вызывать процедуру запуска фонового задания строго после завершения транзакции записи и проведения объекта.
Для этого в форме документа перенесем запуск отправки в событие ПослеЗаписи на клиенте:
&НаКлиенте
Процедура ПослеЗаписи(ПараметрыЗаписи)
// Запускаем отправку только если документ проведен
Если Объект.Проведен Тогда
ЗапуститьФоновуюВыгрузкуНаСервере(Объект.Ссылка);
КонецЕсли;
КонецПроцедуры
&НаСервере
Процедура ЗапуститьФоновуюВыгрузкуНаСервере(СсылкаНаДокумент)
МассивПараметров = Новый Массив;
МассивПараметров.Добавить(СсылкаНаДокумент);
// Запуск процедуры общего модуля в отдельном фоновом потоке
ФоновыеЗадания.Выполнить("ИнтеграцияВыгрузка.ВыгрузитьДокументВФоне", МассивПараметров, , "Выгрузка документа " + Строка(СсылкаНаДокумент));
КонецПроцедуры
Процедура в серверном модуле ИнтеграцияВыгрузка выполняет непосредственное подключение и перенос реквизитов:
Процедура ВыгрузитьДокументВФоне(СсылкаНаДокумент) Экспорт
// Формируем COM-соединение на сервере
Попытка
COMConnector = Новый COMОбъект("V83.COMConnector");
ПараметрыПодключения = "Srvr=""ServerBase"";Ref=""TargetBase"";Usr=""ExchangeUser"";Pwd=""SecretPass"";";
ВнешняяБаза = COMConnector.Connect(ПараметрыПодключения);
// Логика передачи данных объекта
// ...
Исключение
ЗаписьЖурналаРегистрации("Интеграция.Выгрузка", УровеньЖурналаРегистрации.Ошибка, , СсылкаНаДокумент, ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
КонецПопытки;
КонецПроцедуры
Разберем технические нюансы, с которыми можно столкнуться при использовании V83.COMConnector в фоновых заданиях:
rphost. Для успешного создания объекта требуется регистрация 64-битного COM-коннектора или настройка приложения COM+ (суррогатного процесса dllhost.exe).Проанализируем наиболее надежную схему межсистемного взаимодействия, которая полностью изолирует пользователя от возможных сбоев внешней системы и сетевых проблем. Вместо прямого запуска фонового задания на каждый документ создается таблица очереди.
Разберем по шагам реализацию этой схемы:
ОчередьИсходящихСобытий с измерениями Объект (Ссылка на документ) и ресурсами ДатаСоздания, Статус («К отправке», «В обработке», «Ошибка»), КоличествоПопыток.ОбработкаПроведения или через подписку на событие ПриЗаписи создаем запись в регистре очереди со статусом «К отправке». Это выполняется в той же транзакции, гарантируя целостность.
Процедура ВыполнитьВыгрузкуОчереди() Экспорт
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ ПЕРВЫЕ 50
| Очередь.Объект КАК ДокументСсылка
|ИЗ
| РегистрСведений.ОчередьИсходящихСобытий КАК Очередь
|ГДЕ
| Очередь.Статус = ЗНАЧЕНИЕ(Перечисление.СтатусыОтправки.КОтправке)";
Результат = Запрос.Выполнить().Выгрузить();
Если Результат.Количество() = 0 Тогда
Возврат;
КонецЕсли;
// Инициализируем одно соединение на всю пачку документов
// и выполняем пакетную передачу данных
КонецПроцедуры
Посмотрим на современную замену устаревшему механизму COM-соединений. В базе-приемнике создается собственный HTTP-сервис, принимающий данные в формате JSON, а база-источник выполняет асинхронный запрос через объект HTTPСоединение.
Преимущества перехода на HTTP-сервисы:
Использование фоновых заданий в связке с механизмом очереди или легковесными HTTP-сервисами обеспечивает высокую отзывчивость системы для пользователей и гарантирует доставку данных между конфигурациями.