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