Перейти к содержанию

Upsert справочника — создание или обновление

Сценарий. Получить из Kafka сообщение с данными номенклатуры и — создать элемент справочника или обновить существующий по UUID из сообщения.

Ключевые паттерны

  1. ОбщегоНазначения.JSONВЗначение() — разбор JSON с корректной обработкой дат (БСП).
  2. ПолучитьСсылку(Новый УникальныйИдентификатор(...)) — восстановление ссылки по UUID из сообщения.
  3. кфкИнтеграция.Отключить(Объект)обязательно перед Записать(), иначе запись снова попадёт в очередь исходящих.
  4. ОбменДанными.Загрузка = Истина — стандартный флаг для записей при обмене данными.

Код обработчика

Процедура Десериализация(ТелоСообщения, Свойства, ТекстЖурнала, Отказ) Экспорт

    // Второй параметр — поля с датами (будут корректно преобразованы из JSON)
    Данные = ОбщегоНазначения.JSONВЗначение(ТелоСообщения, "dateTime,changedAt", Ложь);

    // Восстанавливаем ссылку по UUID из сообщения — для синхронизации по идентификатору
    СсылкаНаОбъект = ПолучитьСсылку(Новый УникальныйИдентификатор(Данные.ref));
    Объект = СсылкаНаОбъект.ПолучитьОбъект();
    Если Объект = Неопределено Тогда
        // Объект не найден — создаём с тем же UUID (для ссылочной целостности)
        Объект = СоздатьЭлемент();
        Объект.УстановитьСсылкуНового(СсылкаНаОбъект);
    КонецЕсли;

    Объект.Наименование = Данные.name;
    Объект.Код          = Данные.code;

    Объект.Товары.Очистить();
    Для Каждого СтрокаТЧ Из Данные.lines Цикл
        НоваяСтрока = Объект.Товары.Добавить();
        НоваяСтрока.Количество = СтрокаТЧ.qty;
        // НоваяСтрока.Номенклатура = ПолучитьСсылкуНоменклатуры(СтрокаТЧ.item);
    КонецЦикла;

    // Обязательно: предотвратить повторную регистрацию этой записи в очередь исходящих
    кфкИнтеграция.Отключить(Объект);

    Объект.ОбменДанными.Загрузка = Истина;
    Объект.Записать();

КонецПроцедуры

Почему оба вызова обязательны

Отключить() и ОбменДанными.Загрузка — оба

  • Отключить() — блокирует подписку адаптера на событие записи. Иначе запись снова попадёт в исходящие и начнётся бесконечный цикл отправок.
  • ОбменДанными.Загрузка = Истина — стандартный механизм 1С для подавления бизнес-логики (проверок, пересчёта итогов, подписок прикладных подсистем) при загрузке данных из внешней системы.

Идемпотентность

Повторный вызов

Обработчик может быть вызван повторно — при перезапуске или ручном возврате. В этом примере идемпотентность обеспечивается двумя факторами:

  • Элемент ищется по UUID из сообщения.
  • Поля перезаписываются (не добавляются) — табличная часть очищается и заполняется заново.

Повторный вызов с тем же сообщением приведёт к тому же состоянию справочника.

Смотрите также