При выполнении процедуры закрытия месяца или группового перепроведения документов в 1С:Предприятии 8.3 пользователи и программисты нередко сталкиваются с системным сбоем следующего вида:
{Обработка.ГрупповоеПерепроведениеДокументов.МодульМенеджера(1958)}: Ошибка при вызове метода контекста (Записать): В данной транзакции уже происходили ошибки!
При этом ручное перепроведение того же самого документа проходит абсолютно без ошибок. Проанализируем физическую природу этого поведения платформы 1С и разберем пошаговые методы локализации и устранения первопричины сбоя.
Для понимания сути проблемы рассмотрим механизм работы транзакций в платформе 1С:Предприятие. В СУБД (MS SQL Server, PostgreSQL, Oracle) транзакция всегда монолитна и едина для сеанса. Механизм вложенных транзакций в 1С является логическим: реальная транзакция на стороне сервера базы данных открывается только один раз при самом первом вызове метода НачатьТранзакцию().
Если внутри открытой транзакции происходит любая критическая ошибка СУБД (конфликт блокировок, нарушение уникальности индекса, ошибка контроля остатков или сбой триггера), транзакция СУБД безвозвратно помечается как аварийная (концепция «обреченной транзакции» — Doomed Transaction).
Даже если разработчик перехватил эту первоначальную ошибку программно с помощью конструкции Попытка ... Исключение, дальнейшая работа с базой данных внутри текущей транзакции полностью блокируется платформой. Любое следующее действие — будь то запись документа, изменение регистра или фиксация транзакции вызовом ЗафиксироватьТранзакцию() — немедленно вызовет платформенное исключение «В данной транзакции уже происходили ошибки!».
Таким образом, документ и строка кода, указанные в тексте ошибки, являются лишь местом, где транзакция попыталась продолжить работу после ранее произошедшего сбоя, а не истинной причиной проблемы.
Поскольку исходное исключение было перехвачено и скрыто внутри блока Попытка ... Исключение, настроим отладчик на остановку до момента перехвата ошибки.
Отладчик остановит исполнение кода ровно в том месте, где произошел первоначальный сбой. Это позволит увидеть реальный текст ошибки — например, отсутствие остатка по конкретной номенклатуре, деление на ноль в расчете себестоимости или попытку записи в заблокированный регистр.
Если воспроизвести ошибку в режиме отладки невозможно (например, на рабочей многопользовательской базе), настроим сбор Технологического журнала (ТЖ).
Создадим или дополним файл конфигурации logcfg.xml в каталоге настроек платформы (например, C:\Program Files\1cv8\conf\logcfg.xml), настроив перехват событий EXCP и EXCPCNTX:
<config xmlns="http://v8.1c.ru/v8/tech-log">
<log location="C:\Logs\1C_Exceptions" history="4">
<event>
<eq property="name" value="EXCP"/>
</event>
<event>
<eq property="name" value="EXCPCNTX"/>
</event>
<property name="all"/>
</log>
</config>
В полученном журнале событий найдем запись исключения, которая предшествует сообщению о сломанной транзакции. В ней будет содержаться полный контекст сценарного вызова и детализированный текст ошибки СУБД.
Частой причиной описанного сбоя является некорректное обновление нетиповой конфигурации (базы, находящейся на поддержке с возможностью изменения). Если при установке релиза модуль менеджера обработки группового перепроведения или модуль объекта документа не обновился до актуального состояния, возникает рассогласование алгоритмов проведения и логики транзакций.
Разберем порядок восстановления типовых модулей:
.cf того же релиза.Обработка.ГрупповоеПерепроведениеДокументов, модули закрытия месяца) и модули перепроводимых документов (например, Документ.РеализацияТоваровУслуг).По умолчанию типовые механизмы группового проведения объединяют обработку документов в пакеты (порции по 10–100 документов в одной транзакции) для ускорения записи. Если один документ в пакете падает, откат затрагивает все остальные документы порции.
Для гарантированного проведения валидных документов используем стандартную обработку «Групповое перепроведение документов» (раздел Администрирование → Обслуживание → Корректировка данных):
При таком подходе каждый документ обрабатывается в собственной изолированной транзакции: все корректные документы успешно проведутся, а сбойный документ будет точно определен и выведен в итоговый протокол с реальным описанием проблемы.
Параллельная работа регламентных заданий (таких как обмен с банком, фоновое закрытие месяца, синхронизация с внешними базами или сервисами ЭДО) может приводить к неявным взаимоблокировкам таблиц прямо в момент пакетного проведения.
Перед запуском закрытия месяца выполним следующие профилактические действия:
ragent, удаление содержимого каталога snccntx).