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