Как найти проблемный участок кода в 1С, если появилось сообщение «В данной транзакции уже происходили ошибки»

Сегодня поговорим о довольно частой ошибке. Не все специалисты знают, как ее пофиксить. Это статья нашего коллеги Андрея Бурмистрова, эксперта в сфере оптимизации производительности 1С. Разработкой на платформе «1С:Предприятие 8» Андрей занимается уже более 10 лет и знает нюансы. Он расскажет, когда возникает такая проблема и рассмотрит способы решения.
25 ноября 2025

Причина ошибки

Начнем с вымышленного примера, который, подчеркну, НЕ соответствует стандартам разработки в 1С. Это лишь пример. У вас есть такой код.

Начало транзакции - вымышленный пример

Если во время записи данных возникает исключение, система фиксирует это событие в журнале регистрации. На первый взгляд всё выглядит корректно, но на деле нарушаются базовые стандарты разработки. После ошибки при записи данных при последующем чтении константы появится сообщение «В данной транзакции уже происходили ошибки». При этом ошибка фактически произошла раньше — в момент записи, а сама константа к ней не имеет никакого отношения.

ошибка

Проблема в том, что если внутри транзакции используется конструкция Попытка–Исключение, и в блоке Попытка происходит ошибка, связанная с базой данных (например, во время записи), сама транзакция не откатывается, но получает статус «только для отмены». Это означает, что в рамках этой транзакции больше нельзя выполнять никаких действий с базой: ни чтения, ни записи. Единственное возможное действие — её отмена. Формально транзакция остаётся активной, но фактически уже «нежизнеспособна».

Любая последующая попытка обратиться к базе данных из такой транзакции приведёт к сообщению «В данной транзакции уже происходили ошибки». Самое неудобное здесь то, что в тексте ошибки указывается строка кода, где происходит обращение к базе, а не та, где возникла изначальная ошибка — из-за этого найти первопричину становится значительно сложнее.

Настоящая причина появления этой ошибки — нарушение стандартов разработки 1С при обработке ошибок внутри транзакции. Иными словами, проблема кроется в логике кода, а не в платформе.

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

Пример, приведённый выше, довольно простой — здесь начало транзакции, блок Попытка–Исключение и операция записи находятся в одной процедуре. На практике же всё гораздо сложнее: стек вызовов может насчитывать десятки строк, при этом транзакция открывается в одной процедуре, обработка ошибок — в другой, а сама ошибка возникает в третьей. Такая разнесённость логики значительно усложняет анализ и поиск причины сбоя.

Решение проблемы можно разделить на две части:

  1. Найти проблемное место
  2. Исправить код согласно стандартам 1С

Найти проблемное место можно вручную с помощью техжурнала, либо использовать Монитор. Рассмотрим оба способа.

Ищем проблемное место

Способ 1. Ручная настройка техжурнала.

Необходимо настроить технологический журнал следующим образом:

Настройка технологического журнала (logcfg.xml) <?xml version="1.0" encoding="UTF-8"?> <config xmlns="http://v8.1c.ru/v8/tech-log"> <log location="d:\Excp_Sdbl" history="48"> <event>
<eq property="name" value="EXCP"/> <eq property="p:processName" value="Имя базы"/> <eq property="Descr" value="В данной транзакции уже происходили ошибки!"/>
</event> <event> <eq property="name" value="SDBL"/> <eq property="p:processName" value="Имя базы"/> <eq property="Func" value="setRollbackOnly"/> </event> <property name="all"/> </log> </config>

Событие EXCP с фильтром по тексту ошибки позволяет зафиксировать все подобные случаи в журнале регистрации. Особый интерес представляет событие SDBL с фильтром Func=setRollbackOnly — по нему можно определить участок кода, где транзакции был присвоен статус «только для отмены». Если сопоставить эти события по времени и полю t:connectID, удаётся точно понять, в каком месте находится блок Попытка–Исключение, откуда была вызвана процедура, которая привела к ошибке.

Пример лога техжурнала.

49:06.002036-1,SDBL,5,process=rphost,p:processName=Demo_Lock,OSThread=28092,t:clientID=973,t:applicationName=1CV8C,t:computerName=Srv,t:connectID=4163,SessionID=7,Usr=Администратор,AppID=1CV8C,DBMS=DBMSSQL,DataBase=Srv\Demo_Lock,Trans=1,Func=setRollbackOnly,Context='Форма.Вызов : ВнешняяОбработка.Тест.Форма.Форма.Модуль.ПроцедураНаСервере
ВнешняяОбработка.Тест.Форма.Форма.Форма : 30 : Данные.Записать();'
49:06.002043-0,EXCP,6,process=rphost,p:processName=Demo_Lock,OSThread=28092,t:clientID=973,t:applicationName=1CV8C,t:computerName=Srv,t:connectID=4163,SessionID=7,Usr=Администратор,AppID=1CV8C,DBMS=DBMSSQL,DataBase=Srv\Demo_Lock,Exception=DataBaseException,Descr=В данной транзакции уже происходили ошибки!,Context='Форма.Вызов : ВнешняяОбработка.Тест.Форма.Форма.Модуль.ПроцедураНаСервере
ВнешняяОбработка.Тест.Форма.Форма.Форма : 39 : Константа1 = Константы.Константа1.Получить();'

В логах у события SDBL в свойстве Context будет указан стек вызова, который и привел к ошибке. Благодаря этому стеку можно относительно просто найти место в коде, где используется Попытка-Исключение, и переписать этот блок. Как именно его нужно переписать обсудим ниже.

Способ 2. Используем «Монитор».

Для анализа этой проблемы в «Мониторе» необходимо включить показатель «Ошибка ТЖ» и сохранить настройки. 

включить показатель «Ошибка ТЖ» в «Мониторе»

Далее «Монитор» сам настроит техжурнал, сопоставит события, загрузит логи и присвоит каждой ошибке свою категорию. Текст ошибки отображается на соответствующей вкладке.

«Монитор» сам присвоит каждой ошибке свою категорию.

Но самое важное отображается на вкладке «Доп. сведения». Тут отображены события, которые связаны с ошибкой, в нашем случае это SDBL. Здесь видны все значения всех свойств события, в частности свойство Context, содержащее нужные нам сведения.

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

В итоге, какой бы способ мы не использовали, получаем строку кода:

ВнешняяОбработка.Тест.Форма.Форма.Форма : 30 : Данные.Записать();

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

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

необходимо фиксировать транзакцию внутри попытки

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

при возникновении исключения при записи полное описание ошибки попадет в журнал регистрации, а при чтении константы ошибки не будет.

В этом случае причина была в делении на ноль, но из-за некорректного кода эта ошибка скрывалась за ширмой «В данной транзакции уже происходили ошибки». Используя показатель «Ошибка ТЖ» из «Монитора», можно довольно легко выявить и устранить эту проблему.

С 1 января 2026 года меняется лицензионная политика продукта «Монитор»: на каждые 3 сервера необходимо будет покупать лицензию. До конца декабря есть возможность купить лицензию без ограничения по количеству серверов. Свяжитесь с нами, мы предоставим триал-версию на 30 дней и поможем ее установить.


Поделиться в соцсетях:  

Похожие статьи

ESB

Обзор российских ESB-решений

10 подробных технических обзоров на отечественные платформы