При разработке механизмов синхронизации данных в 1С программисты часто сталкиваются с вопросом: как правильно очищать таблицу регистрации изменений? На первый взгляд кажется, что удаление регистрации по конкретной ссылке (объекту) — это простой и понятный путь. Однако на практике такой подход таит в себе серьезные риски потери данных. В этой статье мы подробно разберем внутреннюю логику работы планов обмена, выясним, зачем нужны номера сообщений, и научимся обрабатывать сложные ситуации, такие как частичная выгрузка или передача тяжелых файлов.
Рассмотрим стандартную ситуацию. Мы инициируем обмен, выбираем измененные товары и начинаем их отправку во внешнюю систему. В процессе отправки (который может длиться от нескольких секунд до минут) менеджер в базе 1С открывает карточку одного из этих товаров и меняет его цену или остаток. Система 1С, видя изменение, снова регистрирует этот товар в плане обмена.
Если в конце процесса мы вызовем метод ПланыОбмена.УдалитьРегистрациюИзменений(Узел, Товар), передав туда ссылку на объект, мы совершим критическую ошибку. Мы удалим всю регистрацию для этого товара, включая ту, которая возникла только что из-за действий менеджера. В итоге актуальные данные об изменении цены никогда не попадут в приемник, так как для 1С этот объект больше не считается измененным. Проанализируем, как избежать этой коллизии с помощью механизма номеров сообщений.
Для надежного обмена в 1С реализован механизм «квитирования» (подтверждения). Основная логика заключается в использовании номеров сообщений. Разберем этот процесс по шагам:
Узел.НомерОтправленного + 1.ПланыОбмена.ВыбратьИзменения(Узел, НомерСообщения). В этот момент 1С делает важную вещь: она «помечает» в таблице регистрации все текущие изменения этим номером.ПланыОбмена.УдалитьРегистрациюИзменений(Узел, НомерСообщения).Важный момент: метод удаления по номеру сообщения удаляет только те записи, у которых номер меньше или равен переданному. Те объекты, которые были изменены во время обмена (и получили номер 0), останутся в таблице и будут выгружены в следующий раз. Таким образом, мы гарантируем целостность данных.
Посмотрим на пример кода, который правильно инкрементирует счетчик и выбирает данные для обмена. Важно помнить, что запись номера сообщения в узел должна происходить до или во время формирования пакета.
// Получаем объект узла для изменения номера
УзелОбъект = УзелОбмена.ПолучитьОбъект();
НовыйНомер = УзелОбъект.НомерОтправленного + 1;
// Фиксируем изменения за конкретным номером сообщения
ВыборкаИзменений = ПланыОбмена.ВыбратьИзменения(УзелОбмена, НовыйНомер);
// Здесь логика формирования пакета данных (XML, JSON или HTTP-запрос)
Пока ВыборкаИзменений.Следующий() Цикл
Данные = ВыборкаИзменений.Получить();
// Обработка данных...
КонецЦикла;
// После формирования пакета записываем новый номер в узел
УзелОбъект.НомерОтправленного = НовыйНомер;
УзелОбъект.Записать();
Удаление регистрации должно происходить только после того, как приемник прислал ответ об успешном получении данных. Если вы используете HTTP-сервисы, это будет код ответа 200. Если файловый обмен — получение файла-ответа с номером принятого сообщения.
// Предположим, мы получили подтверждение, что сообщение №45 принято
НомерПринятого = 45;
ПланыОбмена.УдалитьРегистрациюИзменений(УзелОбмена, НомерПринятого);
Часто возникает вопрос: как быть, если пакет данных большой, и один объект из десяти не прошел валидацию на стороне приемника? Если мы не удалим регистрацию по номеру сообщения, то в следующий раз мы снова отправим все 10 товаров, что создает избыточный трафик.
В этом случае у нас есть два пути. Рассмотрим подробнее каждый:
ПланыОбмена.ЗарегистрироватьИзменения(Узел, ОбъектСКосяком). Этот объект снова попадет в очередь, но уже с новым номером сообщения (или с номером 0), и будет отправлен при следующей итерации.Проанализируем ситуацию, когда один товар весит 20 Мб из-за фотографий. Передавать такие объемы через стандартный механизм ВыбратьИзменения() крайне неэффективно, особенно при платном трафике. Выясним, как оптимизировать этот процесс:
Во-первых, не следует хранить бинарные данные картинок прямо в таблице изменений или передавать их в теле основного JSON/XML файла. Используйте разделение: в основном обмене передавайте только ссылку на картинку или её хеш-сумму (MD5). Приемник, получив пакет, сравнит хеш у себя и, если он отличается, сам «придет» за новым файлом через отдельный HTTP-запрос.
Во-вторых, используйте проверку модифицированности. Часто менеджеры пересохраняют карточку товара, не меняя картинку. Чтобы не регистрировать тяжелые данные повторно, в подписке на событие ПередЗаписью стоит сравнивать текущую картинку с уже имеющейся в базе. Если изменений в файле нет — блокируйте авторегистрацию для этого узла.
Подведем итоги нашего анализа. Работа с планами обмена — это не просто выгрузка данных, а управление состояниями объектов. Для построения надежной системы следуйте этим правилам:
ВыбратьИзменения(), чтобы избежать рассинхронизации при сбое кода.УдалитьРегистрациюИзменений эффективно очищает все старые записи, что предотвращает раздувание таблиц регистрации изменений (так называемых «таблиц регистрации» или «log-таблиц»).Помните, что таблицы регистрации изменений имеют свойство накапливать данные, если обмен прерван на долгое время. Регулярно проводите мониторинг количества зарегистрированных изменений, чтобы вовремя заметить проблемы в работе интеграционных сервисов.