Ошибка с текстом «В данной транзакции уже происходили ошибки!» является одной из самых коварных в платформе 1С:Предприятие 8. Она не указывает на саму причину сбоя, а лишь сообщает о том, что внутри текущей транзакции (например, при попытке записи объекта или формировании сообщения обмена) ранее возникло другое исключение. Поскольку транзакция в 1С — это неделимая операция, любая ошибка внутри нее помечает всю транзакцию как «битую», и дальнейшая попытка зафиксировать изменения или выполнить запись приводит к этому вторичному сообщению. Рассмотрим подробнее, как «раскопать» истинную причину проблемы и заставить обмен работать.
Прежде чем переходить к действиям, разберем ситуацию. Когда выполняется синхронизация в распределенной информационной базе (РИБ), система открывает транзакцию. Внутри этой транзакции происходит чтение файла обмена, создание новых объектов или выгрузка измененных. Если при записи какого-то документа (например, из-за проверки в коде или периода запрета) происходит сбой, платформа 1С фиксирует это. Если программист обернул запись в блок Попытка — Исключение, но не прервал выполнение или не откатил транзакцию корректно, следующая же команда Записать() или ЗафиксироватьТранзакцию() выдаст нам пресловутое сообщение о том, что ошибки уже были.
Проанализируем записи Журнала регистрации (ЖР). Это первый и самый важный шаг. Ошибка, которую вы видите в окне обмена, — последняя в очереди. Нам же нужно найти первую.
Типовые механизмы обмена часто объединяют загрузку и выгрузку в один большой процесс. Чтобы понять, на каком этапе происходит сбой, проделаем следующее:
Перейдем в настройки синхронизации данных. Вместо нажатия общей кнопки «Синхронизировать», найдем команду «Состав отправляемых данных» или перейдем в «Сценарии узла информационной базы». Выполним по отдельности сначала загрузку данных, а затем выгрузку.
Рассмотрим пример из практики: при выполнении общей синхронизации вылетает общая ошибка транзакции. Но если зайти в Синхронизация данных — Настройки — Еще — Выполнить загрузку данных, система может выдать гораздо более информативное сообщение, например: «Задание для расчета себестоимости нельзя записать в запрещенном периоде». Это происходит потому, что при ручном запуске отдельных этапов контекст выполнения меняется, и платформа может вывести первичное исключение напрямую пользователю.
Выясним, не пытаются ли данные из другой базы «залететь» в закрытый период. Это классическая причина сбоев в РИБ. Даже если в базе-источнике документ был изменен законно, база-приемник может иметь более жесткие настройки периода запрета.
Проверим настройки:
Если Журнал регистрации молчит, а разделение обмена не помогает, воспользуемся инструментами разработчика. Проанализируем ситуацию программно:
Платформа прервет выполнение кода в тот момент, когда возникнет самое первое исключение. Посмотрим на стек вызовов. Скорее всего, вы увидите ошибку в одном из обработчиков: ПередЗаписью, ПриЗаписи или в модуле плана обмена. Это позволит точно определить объект (документ или справочник), на котором «спотыкается» транзакция.
Иногда причина кроется в «зависших» индексах или битых временных файлах на сервере или локальной машине. Выполним профилактические действия:
%AppData%\1C\1cv8.Проанализируем ситуацию, когда ошибка подавляется. Допустим, в модуле объекта есть такой код:
Процедура ПередЗаписью(Отказ)
Если ОбменДанными.Загрузка Тогда
Возврат;
КонецЕсли;
Попытка
// Некая логика, которая вызывает ошибку
Справочники.Склады.НайтиПоНаименованию("Основной").Записать();
Исключение
// Ошибка поймана, но транзакция уже испорчена!
ЗаписьЖурналаРегистрации("Ошибка записи", УровеньЖурналаРегистрации.Ошибка);
КонецПопытки;
КонецПроцедуры
В данном примере, если Записать() внутри блока Попытка завершится неудачей, транзакция пометится как ошибочная. Даже если мы «проглотили» ошибку, при попытке завершить основную транзакцию обмена 1С выдаст нам сообщение о том, что в этой транзакции уже происходили ошибки. Решение: всегда проверяйте корректность вложенных записей и старайтесь не использовать запись других объектов внутри транзакций обмена без крайней необходимости.
Подводя итог: для решения проблемы всегда ищем первоисточник через Журнал регистрации или отладку, проверяем даты запрета изменения и пробуем выполнить загрузку данных отдельно от выгрузки.