При переходе на новые релизы 1С:Бухгалтерия предприятия 3.0 (например, при обновлении с версии 3.0.169.18 и выше) специалисты часто сталкиваются с критической остановкой процесса обновления. Система выдает сообщение следующего вида: Ошибка выполнения обработчика обновления Справочники.РегламентированныеОтчеты.ЗаполнитьСписокРегламентированныхОтчетов: Открытая внутри обработчика обновления транзакция осталась активной (не была закрыта или отменена). Рассмотрим подробно, почему возникает эта ситуация и как ее исправить, если стандартные средства тестирования базы не помогают.
Прежде всего, разберем механику проблемы. Сообщение о «незакрытой транзакции» в контексте 1С почти всегда является маскировочным. На самом деле внутри транзакции происходит какая-то другая ошибка (например, нарушение уникальности данных или отказ в доступе), которая вызывает исключение. Если код обработчика в блоке Попытка...Исключение некорректно обрабатывает выход из транзакции, платформа сообщает лишь о том, что транзакция «зависла».
В случае со справочником РегламентированныеОтчеты проблема обычно заключается в том, что обработчик обновления пытается программно создать или обновить записи, которые уже существуют в базе, но имеют конфликтующие идентификаторы или дублирующиеся служебные наименования. Проанализируем ситуацию: обработчик ЗаполнитьСписокРегламентированныхОтчетов сопоставляет данные в конфигурации с данными в справочнике. Если он находит два отчета с одинаковым внутренним именем (даже если один из них помечен на удаление), срабатывает логический тупик.
Перед началом любых манипуляций обязательно создадим резервную копию информационной базы. Опыт показывает, что стандартное «Тестирование и исправление» (реиндексация, проверка логической целостности) в данном случае редко приносит результат, так как данные физически целы, но логически противоречивы.
Важным моментом, который часто упускают, является активность фоновых процессов. Выясним, не мешают ли регламентные задания работе обработчика. Перед запуском обновления рекомендуем выполнить следующие действия:
Иногда именно блокировка со стороны другого процесса (например, фонового обновления классификаторов) не дает закрыться транзакции в основном потоке обновления.
Как показывает практика, основной виновник — дубли записей. Причем они могут не отображаться как одинаковые строки в обычном списке. Нам нужно проверить справочник РегламентированныеОтчеты на наличие записей с одинаковыми именами макетов или кодами. Рассмотрим, как это сделать с помощью консоли запросов.
Выполним следующий запрос, чтобы найти подозрительные объекты:
ВЫБРАТЬ
РегламентированныеОтчеты.Источник КАК Источник,
КОЛИЧЕСТВО(РАЗЛИЧНЫЕ РегламентированныеОтчеты.Ссылка) КАК Количество
ИЗ
Справочник.РегламентированныеОтчеты КАК РегламентированныеОтчеты
ГДЕ
НЕ РегламентированныеОтчеты.ПометкаУдаления
СГРУППИРОВАТЬ ПО
РегламентированныеОтчеты.Источник
ИМЕЮЩИЕ
КОЛИЧЕСТВО(РАЗЛИЧНЫЕ РегламентированныеОтчеты.Ссылка) > 1
Если запрос вернул строки, значит, в системе присутствуют отчеты, претендующие на один и тот же «источник» (внутреннее имя в конфигурации). Проанализируем эти записи. Часто бывает так, что один отчет является актуальным, а второй — устаревшим «хвостом» от предыдущих некорректных обновлений. В этом случае лишние записи необходимо либо удалить окончательно (через «Удаление помеченных объектов»), либо переименовать их Источник, чтобы снять конфликт уникальности.
Если поиск дублей запросом не дал явного результата, перейдем к более глубокому анализу. Запустим базу в режиме конфигуратора и найдем процедуру ЗаполнитьСписокРегламентированныхОтчетов. Посмотрим на структуру кода:
НачатьТранзакцию();
Попытка
// Здесь происходит заполнение справочника
Справочники.РегламентированныеОтчеты.СоздатьЭлемент()...
ЗафиксироватьТранзакцию();
Исключение
// Если здесь нет ОтменитьТранзакцию(), мы получим нашу ошибку
ЗаписатьЛогОшибки(ОписаниеОшибки());
КонецПопытки;
Установим точку останова на начале транзакции и пройдем процедуру по шагам (клавиша F10). Нам нужно поймать момент, когда выполнение переходит в блок Исключение. Именно в этот момент в переменной ОписаниеОшибки() будет содержаться истинная причина сбоя. Чаще всего там обнаруживается текст: «Значение поля "Источник" не уникально» или аналогичное сообщение о нарушении прав доступа к конкретному объекту.
Иногда корень зла кроется не в самих отчетах, а в системных идентификаторах. Проанализируем состояние справочника ИдентификаторыОбъектовМетаданных. Если обновление конфигурации прошло успешно, а обновление данных падает, попробуем запустить процедуру обновления идентификаторов принудительно. Для этого можно воспользоваться внешней обработкой «Инструменты разработчика» или запустить базу с параметром ЗапуститьОбновлениеИнформационнойБазы.
Если вы используете версию платформы 8.3.24.1667 или 8.3.25.1374 и выше, обратите внимание на усиленный контроль транзакций в этих версиях. Рассмотрим еще несколько советов:
Наименование и Код на произвольные значения, чтобы обработчик обновления смог создать новую «чистую» запись.Подведем итог: ошибка с активной транзакцией при заполнении регламентированных отчетов — это почти всегда сигнал о том, что в справочнике РегламентированныеОтчеты завелись дубли по ключевым полям (Источник, ИмяМакета). После их устранения и очистки помеченных объектов обновление, как правило, проходит в штатном режиме без дополнительных трудностей.