Как предотвратить прерывание обмена УниверсальныйОбменДаннымиXML при ошибках через COM-соединение?

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

Рассмотрим распространенную проблему, возникающую при настройке двустороннего обмена между базами 1С с использованием обработки УниверсальныйОбменДаннымиXML и планов обмена. Часто обмен настраивают через прямое COM-соединение, устанавливая флажок Обработка.НепосредственноеЧтениеВИБПриемнике = Истина. Проблема заключается в следующем: если за день регистрируется множество документов, и при выгрузке пакета один из них вызывает ошибку в базе-приемнике (например, при проведении или записи), весь процесс обмена экстренно прекращается.

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

Почему обмен прерывается и не помогает обработка исключений?

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


Попытка
    Обработка.ВыполнитьВыгрузку();
Исключение
    // Отказ = ИСТИНА; // Закомментировали, чтобы продолжить
    Сообщение = ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
    ЗаписьЖурналаРегистрации("Обмен данными", УровеньЖурналаРегистрации.Ошибка, , , Сообщение);
КонецПопытки;

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

Выполнение метода прерывается, и код просто не доходит до команды очистки регистрации изменений успешных объектов. Также из-за специфики COM-соединения база-источник получает лишь общую ошибку платформы, а детальное описание того, что именно не провелось в приемнике, теряется при обрыве.

Решение 1: Глушение ошибок в правилах конвертации (КД 2.0)

Если вы хотите сохранить архитектуру на COM-соединении, ошибку необходимо перехватывать на стороне самой базы-приемника, до того, как она обрушит соединение. Сделать это можно в правилах «Конвертации данных 2».

  1. Откройте правила конвертации в конфигурации «Конвертация данных».
  2. Перейдите к правилам конвертации объектов (ПКО), которые вызывают ошибки.
  3. В обработчиках событий, например, ПослеЗагрузки или ПриЗаписи, оберните код проведения или записи в блок Попытка ... Исключение ... КонецПопытки.
  4. В блоке исключения пропишите отказ от записи конкретного проблемного объекта: Отказ = Истина;.
  5. Там же добавьте принудительную запись текста ошибки в Журнал регистрации базы-приемника.

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

Решение 2: Переход на пообъектную выгрузку через Веб-сервисы

Рассмотрим более современный и отказоустойчивый подход, к которому пришел автор темы. COM-соединения часто работают нестабильно при больших объемах данных и чувствительны к разнице версий платформ. Веб-сервисы (HTTP-запросы) работают по принципу без сохранения состояния (stateless), они намного легче переносят обрывы связи и изолируют ошибки.

Разберем логику реализации пообъектного обмена:

  1. Выборка изменений: В базе-источнике в цикле перебираем выборку регистрации изменений по узлу плана обмена.
  2. Формирование пакета: Помещаем зарегистрированные объекты в массив.
  3. Генерация XML: В следующем цикле обходим полученный массив. Для каждого отдельного объекта формируем индивидуальный XML-файл с помощью типовой обработки УниверсальныйОбменДаннымиXML.
  4. Отправка данных: Передаем полученную XML-строку (или файл) на специально подготовленный веб-сервис базы-приемника.
  5. Загрузка в приемнике: В модуле веб-сервиса базы-приемника прописан код, который принимает XML и загружает его через ту же обработку УниверсальныйОбменДаннымиXML. Если возникает ошибка, она обрабатывается и логируется локально в приемнике, а веб-сервис возвращает ответ источнику о неудаче.
  6. Снятие с регистрации: Если веб-сервис вернул успешный ответ, база-источник снимает регистрацию изменения только для этого конкретного выгруженного объекта.

Посмотрим на общую схему цикла в источнике (псевдокод):


// Получаем выборку изменений
Выборка = ПланыОбмена.ВыбратьИзменения(УзелОбмена, НомерСообщения);
Пока Выборка.Следующий() Цикл
    ОбъектДанных = Выборка.Получить();
    
    // Формируем XML для одного объекта
    XMLСтрока = СформироватьXMLДляОбъекта(ОбъектДанных, ПравилаОбмена);
    
    // Отправляем через веб-сервис
    Результат = ПроксиВебСервиса.ЗагрузитьОбъект(XMLСтрока);
    
    Если Результат = "Успех" Тогда
        // Снимаем регистрацию только для успешного объекта
        ПланыОбмена.УдалитьРегистрациюИзменений(УзелОбмена, ОбъектДанных);
    Иначе
        ЗаписьЖурналаРегистрации("Обмен данными", УровеньЖурналаРегистрации.Ошибка, , ОбъектДанных, "Ошибка загрузки: " + Результат);
    КонецЕсли;
КонецЦикла;

Проверка модулей объектов

Также перед внедрением любых сложных доработок убедитесь, что в модулях объектов баз-приемников корректно обрабатывается флаг загрузки. Часто ошибки проведения при обмене возникают из-за проверок заполнения, которые должны выполняться только при интерактивной работе пользователя.

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


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

Переход от громоздкого COM-соединения к пообъектной выгрузке через веб-сервисы или HTTP-сервисы является лучшей практикой при построении надежных обменов между информационными базами 1С. Это гарантирует, что ошибка в одном документе никогда не заблокирует передачу остальных критически важных данных предприятия.

← На главную