Как правильно снимать регистрацию изменений в плане обмена при передаче данных через веб-сервисы в 1С?

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

При построении обмена между базами 1С с использованием веб-сервисов и универсальной обработки выгрузки/загрузки данных в формате XML (типовая обработка V8Exch82 или аналогичные) часто возникает задача контролировать снятие объектов с регистрации. Если просто удалить регистрацию изменений у всех выгруженных объектов сразу после формирования файла, существует риск потери данных: приемник может не получить файл или аварийно завершить загрузку из-за ошибки в данных.

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

Особенности загрузки данных и риски пообъектного контроля

На первый взгляд кажется заманчивой идея отслеживать статус записи каждого элемента в базе-приемнике и передавать в базу-источник список ссылок или уникальных идентификаторов (ГУИД), загруженных "Успешно". Однако при таком подходе возникают серьезные технические ограничения:

  1. Транзакционность загрузки: Типовая обработка загрузки данных работает порциями внутри транзакций (параметры ЗагружатьДанныеВТранзакции и КоличествоЭлементовВТранзакции). Если при загрузке 9-го элемента из 10 происходит ошибка, платформа откатывает всю транзакцию. Элементы, обработанные ранее в этой порции, физически не запишутся в базу, хотя алгоритм отслеживания уже мог зафиксировать их как "загруженные".
  2. Отключение транзакций: Если отключить транзакции, объекты начнут записываться поштучно, но при сбое пакета в приемнике образуются "битые ссылки" и нарушится ссылочная целостность данных.
  3. Атомарность пакета: В концепции обменов 1С пакет выгрузки рассматривается как единое целое. Если пакет загружен частично, целостность данных считаются нарушенной, и такой пакет должен откатываться полностью.

Использование механизма номеров сообщений плана обмена

Для решения задачи гарантии доставки данных в платформе 1С предусмотрен встроенный механизм квитирования. Вместо поштучного контроля ГУИД-ов проанализируем схему с использованием номеров сообщений НомерСообщения узла плана обмена.

Рассмотрим алгоритм работы этой схемы по шагам:

  1. при выгрузке пакета из базы-источника (База А) формируется очередное сообщение обмена. Платформа или обработка фиксирует текущий номер отправляемого сообщения для каждого зарегистрированного объекта;
  2. выгруженный XML-файл (или его содержимое) отправляется в базу-приемник (База Б) через веб-сервис;
  3. база Б выполняет загрузку полученного файла в единой транзакции;
  4. при успешном завершении загрузки база Б возвращает базе А подтверждение (квитанцию), содержащее номер успешно прочитанного сообщения;
  5. получив подтверждение, база А вызовет метод ПланыОбмена.УдалитьРегистрациюИзменений() с указанием узла и номера подтвержденного сообщения.

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

Пример реализации снятия регистрации по номеру сообщения

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

Сначала при формировании выгрузки в базе-источнике фиксируется запись сообщения:


// Запись сообщения в источнике перед выгрузкой
ЗаписьСообщения = ПланыОбмена.ЗаписатьИзменения(УзелОбмена);
НомерОтправленногоСообщения = ЗаписьСообщения.НомерСообщения;

// Далее выполняется выгрузка данных в файл через обработку Конвертации Данных
// Файл передается в веб-сервис базы-приемника...

Далее веб-сервис базы-приемника принимает данные и возвращает результат выполнения. Если от приемника получено подтверждение об успешной загрузке пакета с конкретным номером сообщения, в базе-источнике выполняется удаление регистрации:


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

Альтернативный вариант: пообъектный сбор статусов в Конвертации данных 2.0

Если бизнес-требования жестко регламентируют необходимость получения детального отчета по каждому объекту (например, для вывода списка ошибок пользователю без остановки загрузки остальных данных), можно использовать обработчики событий в правилах конвертации объектов (ПКО):

  1. В обработчике «После загрузки объекта» в приемнике добавляем ссылки на успешно записанные объекты в глобальный параметр-массив Параметры.МассивУспешныхЗагрузок.
  2. В обработчике «При ошибке загрузки» перехватываем исключение, фиксируем ГУИД объекта и текст ошибки в параметр Параметры.ТаблицаОшибок.
  3. По окончании работы обработки V8Exch82 формируем структуру ответа веб-сервиса и передаем ее обратно в базу-источник.
  4. В источнике обходим список успешных ГУИД-ов и выборочно вызываем снятие регистрации по конкретным ссылкам:

// Удаление регистрации конкретного объекта по ссылке
ПланыОбмена.УдалитьРегистрациюИзменений(УзелОбмена, СсылкаНаОбъект);

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

← На главную