Как исправить ошибку «В данной транзакции уже происходили ошибки» при обмене между КА, ERP и Документооборотом?

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

При настройке синхронизации между конфигурациями 1С, такими как «Комплексная автоматизация» (КА), ERP или «Документооборот» (ДО), технические специалисты часто сталкиваются с неприятным сбоем. В процессе загрузки данных выполнение прерывается сообщением: Ошибка записи объекта. В данной транзакции уже происходили ошибки!. Эта ситуация коварна тем, что текст ошибки не указывает на истинную причину сбоя, а лишь констатирует факт «отравления» текущей транзакции предыдущим необработанным исключением.

В данной статье мы подробно разберем, почему возникает эта проблема, проанализируем поведение системы в отладчике и внедрим проверенное решение, которое остается актуальным уже более десяти лет.

Анализируем природу ошибки транзакции

Давайте разберемся в механике работы платформы 1С. Когда мы видим сообщение В данной транзакции уже происходили ошибки, это означает, что внутри одной логической транзакции (например, при попытке записи справочника ФизическиеЛица) произошел какой-то сбой. Платформа фиксирует состояние ошибки, и любые последующие попытки вызвать метод Записать() в этом же блоке кода будут выдавать данное сообщение, пока транзакция не будет полностью отменена.

В контексте обмена через обработку «Конвертация объектов информационных баз», проблема часто локализуется в модуле объекта на этапе фиксации соответствий. Система пытается записать объект, но перед этим или в процессе срабатывают подписки на события, которые пытаются зарегистрировать изменения или сопоставить идентификаторы (GUID) в разных базах.

Поиск «слабого звена» через отладчик

Рассмотрим ситуацию, описанную в обсуждении. При отладке выясняется, что сбой происходит в строке:

ОбменДанными.Получатели.Добавить(Отбор.УзелИнформационнойБазы.Значение);

На первый взгляд, код кажется корректным: мы просто добавляем узел плана обмена в набор получателей, чтобы изменения были зарегистрированы для конкретной базы. Однако именно здесь система может споткнуться, если объект, который мы пытаемся записать, не сконфигурирован должным образом для участия в данном плане обмена. Выясним причину глубже: почему добавление узла в получатели вызывает крах транзакции?

Ключевое решение: работа с составом плана обмена

Проанализировав практический опыт многих разработчиков, мы приходим к выводу, что корень проблемы кроется в метаданных. Для корректной работы механизмов БСП (Библиотеки стандартных подсистем), которые отвечают за сопоставление объектов между базами, необходимо, чтобы вспомогательные регистры входили в «периметр» обмена.

Основное решение: необходимо включить регистр сведений СоответствияОбъектовИнформационныхБаз в состав используемого плана обмена.

Выполним это по шагам:

  1. Откроем базу в режиме «Конфигуратор».
  2. Найдем ветку ПланыОбмена и выберем тот план, через который настроен обмен (например, ОбменДокументооборот или СинхронизацияДанныхЧерезУниверсальныйФормат).
  3. Перейдем на вкладку «Состав».
  4. Найдем в списке объектов РегистрСведений.СоответствияОбъектовИнформационныхБаз.
  5. Установим для него флаг включения в состав.
  6. Сохраним конфигурацию и обновим базу данных.

Этот регистр отвечает за хранение связей между внутренним идентификатором объекта в текущей базе и идентификатором в базе-приемнике. Если его нет в составе плана обмена, попытка системы автоматически зарегистрировать «связку» объектов при загрузке вызывает внутренний конфликт прав или логики, что и приводит к откату всей транзакции.

Дополнительная проверка: использование флага «Загрузка»

Посмотрим на ситуацию со стороны программного кода. При написании собственных обработчиков или модификации типовых подписок на события крайне важно учитывать, в каком режиме записывается объект. Если объект пришел из другой базы, у него должен быть установлен флаг ОбменДанными.Загрузка = Истина.

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


Процедура ПередЗаписью(Отказ)
    // Если объект загружается из обмена, прерываем выполнение стандартных проверок
    Если ОбменДанными.Загрузка Тогда
        Возврат;
    КонецЕсли;

    // Логика добавления узла в получатели
    Если ЗначениеЗаполнено(ЭтотУзел) Тогда
        ОбменДанными.Получатели.Добавить(ЭтотУзел);
    КонецЕсли;
КонецПроцедуры

Использование этого флага позволяет «пропустить» выполнение прикладных триггеров, которые могут конфликтовать с данными, приходящими извне. Однако, как показывает практика с регистром СоответствияОбъектовИнформационныхБаз, даже флаг загрузки не всегда спасает, если нарушена целостность состава метаданных в плане обмена.

Почему это актуально для ERP и КА?

Интересно заметить, что даже в современных версиях 1С:ERP и 1С:Комплексная автоматизация этот регистр иногда забывают включить в типовые планы обмена «из коробки». Это связано с тем, что механизмы обмена постоянно эволюционируют (переход с Конвертации данных 2.0 на 3.0/XDTO), но старые механизмы регистрации соответствий все еще активно используются под капотом БСП.

Если вы работаете с «бесшовной интеграцией» или используете правила, написанные вручную в КД 2.0, включение регистра соответствий в состав плана обмена является обязательным гигиеническим минимумом для стабильной работы системы.

Резюме

Мы выяснили, что ошибка В данной транзакции уже происходили ошибки — это лишь симптом, а не болезнь. Для окончательного исправления ситуации при обмене между КА, ERP и ДО мы рекомендуем:

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

← На главную