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