При настройке синхронизации между конфигурациями 1С, такими как «Комплексная автоматизация» (КА), ERP или «Документооборот» (ДО), технические специалисты часто сталкиваются с неприятным сбоем. В процессе загрузки данных выполнение прерывается сообщением: Ошибка записи объекта. В данной транзакции уже происходили ошибки!. Эта ситуация коварна тем, что текст ошибки не указывает на истинную причину сбоя, а лишь констатирует факт «отравления» текущей транзакции предыдущим необработанным исключением.
В данной статье мы подробно разберем, почему возникает эта проблема, проанализируем поведение системы в отладчике и внедрим проверенное решение, которое остается актуальным уже более десяти лет.
Давайте разберемся в механике работы платформы 1С. Когда мы видим сообщение В данной транзакции уже происходили ошибки, это означает, что внутри одной логической транзакции (например, при попытке записи справочника ФизическиеЛица) произошел какой-то сбой. Платформа фиксирует состояние ошибки, и любые последующие попытки вызвать метод Записать() в этом же блоке кода будут выдавать данное сообщение, пока транзакция не будет полностью отменена.
В контексте обмена через обработку «Конвертация объектов информационных баз», проблема часто локализуется в модуле объекта на этапе фиксации соответствий. Система пытается записать объект, но перед этим или в процессе срабатывают подписки на события, которые пытаются зарегистрировать изменения или сопоставить идентификаторы (GUID) в разных базах.
Рассмотрим ситуацию, описанную в обсуждении. При отладке выясняется, что сбой происходит в строке:
ОбменДанными.Получатели.Добавить(Отбор.УзелИнформационнойБазы.Значение);
На первый взгляд, код кажется корректным: мы просто добавляем узел плана обмена в набор получателей, чтобы изменения были зарегистрированы для конкретной базы. Однако именно здесь система может споткнуться, если объект, который мы пытаемся записать, не сконфигурирован должным образом для участия в данном плане обмена. Выясним причину глубже: почему добавление узла в получатели вызывает крах транзакции?
Проанализировав практический опыт многих разработчиков, мы приходим к выводу, что корень проблемы кроется в метаданных. Для корректной работы механизмов БСП (Библиотеки стандартных подсистем), которые отвечают за сопоставление объектов между базами, необходимо, чтобы вспомогательные регистры входили в «периметр» обмена.
Основное решение: необходимо включить регистр сведений СоответствияОбъектовИнформационныхБаз в состав используемого плана обмена.
Выполним это по шагам:
ПланыОбмена и выберем тот план, через который настроен обмен (например, ОбменДокументооборот или СинхронизацияДанныхЧерезУниверсальныйФормат).РегистрСведений.СоответствияОбъектовИнформационныхБаз.Этот регистр отвечает за хранение связей между внутренним идентификатором объекта в текущей базе и идентификатором в базе-приемнике. Если его нет в составе плана обмена, попытка системы автоматически зарегистрировать «связку» объектов при загрузке вызывает внутренний конфликт прав или логики, что и приводит к откату всей транзакции.
Посмотрим на ситуацию со стороны программного кода. При написании собственных обработчиков или модификации типовых подписок на события крайне важно учитывать, в каком режиме записывается объект. Если объект пришел из другой базы, у него должен быть установлен флаг ОбменДанными.Загрузка = Истина.
Проанализируем пример кода, который помогает избежать лишних проверок и регистрации изменений при загрузке данных:
Процедура ПередЗаписью(Отказ)
// Если объект загружается из обмена, прерываем выполнение стандартных проверок
Если ОбменДанными.Загрузка Тогда
Возврат;
КонецЕсли;
// Логика добавления узла в получатели
Если ЗначениеЗаполнено(ЭтотУзел) Тогда
ОбменДанными.Получатели.Добавить(ЭтотУзел);
КонецЕсли;
КонецПроцедуры
Использование этого флага позволяет «пропустить» выполнение прикладных триггеров, которые могут конфликтовать с данными, приходящими извне. Однако, как показывает практика с регистром СоответствияОбъектовИнформационныхБаз, даже флаг загрузки не всегда спасает, если нарушена целостность состава метаданных в плане обмена.
Интересно заметить, что даже в современных версиях 1С:ERP и 1С:Комплексная автоматизация этот регистр иногда забывают включить в типовые планы обмена «из коробки». Это связано с тем, что механизмы обмена постоянно эволюционируют (переход с Конвертации данных 2.0 на 3.0/XDTO), но старые механизмы регистрации соответствий все еще активно используются под капотом БСП.
Если вы работаете с «бесшовной интеграцией» или используете правила, написанные вручную в КД 2.0, включение регистра соответствий в состав плана обмена является обязательным гигиеническим минимумом для стабильной работы системы.
Мы выяснили, что ошибка В данной транзакции уже происходили ошибки — это лишь симптом, а не болезнь. Для окончательного исправления ситуации при обмене между КА, ERP и ДО мы рекомендуем:
РегистрСведений.СоответствияОбъектовИнформационныхБаз.ОбменДанными.Загрузка.Следуя этим инструкциям, вы обеспечите бесперебойную синхронизацию данных и избавитесь от загадочных падений транзакций, которые преследуют разработчиков 1С уже второе десятилетие.