Как исправить ошибку «В данной транзакции уже происходили ошибки!» при отложенном обновлении УТ 11

Программист 1С v8.3 (Управляемые формы) 1С:Управление торговлей Управленческий учет IT и автоматизация бизнеса
← На главную

В процессе обновления крупных баз данных конфигурации 1С:Управление торговлей 11 (особенно при переходе между релизами ветки 11.4, например с 11.4.7.114 на 11.4.7.141) администраторы и разработчики часто сталкиваются со сбоями отложенных обработчиков. Один из наиболее неприятных и неинформативных сбоев связан с обработкой регистра сведений СуммыДокументовВВалютеРегл.

Система выдает критическую ошибку в общем модуле ДлительныеОперации.Модуль(376) с текстом: «В данной транзакции уже происходили ошибки!». При этом Журнал регистрации молчит, а стандартные точки останова в процедуре обновления игнорируются, поскольку процесс выполняется в фоновом задании. В этой статье мы подробно разберем природу данной ошибки, выясним, почему она маскирует реальную проблему, и рассмотрим четыре практических метода поиска и устранения первопричины.

Теоретическая часть: почему возникает эта ошибка?

Механизм платформы 1С:Предприятие 8 устроен таким образом, что любая ошибка обращения к СУБД (например, деление на ноль в запросе, нарушение уникальности записей, ошибка блокировки или отсутствие прав доступа) мгновенно помечает текущую транзакцию базы данных как «сломанную» (в статус только для отмены). Дальнейшая запись в базу или чтение данных внутри этой транзакции невозможны.

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

При отложенном обновлении регистра СуммыДокументовВВалютеРегл наиболее частыми первопричинами сбоя являются:

  1. Нулевой курс или кратность валюты. Если в исторических документах фигурирует валюта, курс которой на дату проведения документа равен нулю (или не заполнена кратность), то при пересчете управленческих и регламентированных сумм алгоритм выполняет деление на ноль внутри SQL-запроса. Это ломает транзакцию.
  2. «Битые» ссылки в аналитике. Наличие документов или записей регистра с незаполненными ключевыми реквизитами или ссылками типа «Объект не найден».
  3. Блокировки СУБД. Если обновление выполняется на работающей базе, параллельные процессы пользователей могут вызвать взаимоблокировку (Deadlock).

Проанализируем детально способы, которые помогут нам «размотать» эту ошибку до исходного уровня.

Метод 1. Запуск отложенного обновления в один поток (интерактивно)

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

Для реализации этого метода выполним следующие шаги:

  1. Полностью завершим работу всех пользователей и остановим службу планировщика регламентных заданий.
  2. Запустим систему 1С:Предприятие в режиме Тонкого или Толстого клиента, передав специальный параметр запуска. Для этого в окне запуска 1С выберем нашу базу, нажмем кнопку «Изменить», перейдем на вкладку «Дополнительные параметры запуска» и вставим строку:

/C СтартОтложенногоОбновленияВПервомПотоке

При запуске с таким ключом система выполнит отложенные обработчики обновления последовательно в текущем сеансе. При возникновении ошибки деления на ноль или отсутствия курса валюты программа остановит работу и выдаст окно с подробным описанием реальной ошибки и ссылкой на конкретный документ-виновник.

Метод 2. Настройка отладки фоновых заданий в Конфигураторе

Если первый метод по каким-то причинам не дал результатов (например, процедура вызывается только в рамках жестко прописанной фоновой структуры), нам потребуется подключить отладчик напрямую к фоновому заданию обновления. Разберем этот процесс по шагам:

  1. Откроем базу данных в режиме «Конфигуратор».
  2. В главном меню перейдем в раздел Отладка -> Подключение....
  3. В открывшемся окне нажмем кнопку Автоматическое подключение.
  4. Установим флажок напротив пункта Фоновые задания и нажмем «ОК». Теперь Конфигуратор будет автоматически перехватывать все фоновые процессы, запускаемые на сервере или в файловой базе.
  5. Настроим остановку по ошибке. Для этого перейдем в меню Отладка -> Остановка по ошибке....
  6. Установим галочку Останавливаться по ошибке. Крайне важно: снимите флажок «Исключать встроенные ошибки кода платформы» (или аналогичный фильтр системных ошибок), чтобы отладчик среагировал на самое первое исключение внутри блока Попытка еще до того, как транзакция перейдет в статус ошибки.
  7. Запустим сеанс «1С:Предприятие» и инициируем повторный запуск отложенного обновления (через форму «Поддержка и обслуживание» -> «Обновление программы» -> «Результаты обновления»).

При возникновении первичного сбоя (например, на строке расчета курса) отладчик мгновенно остановит выполнение кода. Мы сможем открыть табло и проанализировать значения переменных, чтобы понять, на каком документе или валюте споткнулся алгоритм.

Метод 3. Сбор логов через Технологический журнал

Для клиент-серверных баз, где отладка на сервере может быть заблокирована политиками безопасности или брандмауэром, самым надежным способом является сбор Технологического журнала (ТЖ). Мы можем настроить ТЖ так, чтобы он фиксировал только исключительные ситуации (событие EXCP).

Для этого на сервере 1С в каталоге настроек (обычно это C:\Program Files\1cv8\conf) создадим текстовый файл с именем logcfg.xml и следующим содержимым:


<config xmlns="http://v8.1c.ru/8.2/mngcfg">
  <log location="C:\1C_Logs\Errors" history="1">
    <event>
      <eq property="Name" value="EXCP"/>
    </event>
    <property name="AllProperties"/>
  </log>
</config>

Убедимся, что у учетной записи, от имени которой запущен сервер 1С:Предприятие, есть полные права на запись в папку C:\1C_Logs\Errors. После этого запустим процесс обновления. Как только возникнет ошибка, откроем созданный лог-файл в текстовом редакторе. Изучим последние строки перед падением транзакции: там будет четко зафиксирована исходная ошибка СУБД (например, division by zero) с указанием внутреннего идентификатора сбойной записи.

Метод 4. Временная модификация кода обработчика

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

Найдем процедуру ОбработатьДанныеДляПереходаНаНовуюВерсию в модуле менеджера регистра сведений СуммыДокументовВВалютеРегл. Проанализируем ее структуру. Там будет присутствовать цикл обхода выборки документов, обернутый в транзакцию и попытку. Модернизируем блок исключения следующим образом:


Попытка
    // Оригинальный код обработки и записи набора данных
Исключение
    ТекстОшибкиДляЛога = "Ошибка при обработке документа: " + Строка(ВыборкаДокументов.Регистратор) 
        + " Описание: " + ОписаниеОшибки();
    ЗаписьЖурналаРегистрации("ОбновлениеСуммВалюты", УровеньЖурналаРегистрации.Ошибка,,, ТекстОшибкиДляЛога);
    ВызватьИсключение; // Позволяем транзакции откатиться штатно
КонецПопытки;

Благодаря этому изменению до момента окончательного краха транзакции в Журнал регистрации запишется понятное и детальное сообщение с указанием конкретного документа (например, Приходный ордер №... от ...) и реальной причиной (например, курс валюты равен 0).

Как избавиться от сообщения «Обновление программы не завершено»?

После того как вы найдете и исправите поврежденные данные (заполните курсы валют, исправите битые ссылки), может возникнуть ситуация, когда при каждом входе в программу все равно появляется предупреждение о незавершенном обновлении.

Для того чтобы принудительно очистить этот статус и перезапустить или завершить процесс, выполните следующие действия:

  1. Воспользуйтесь стандартной обработкой «Результаты обновления программы» (раздел Администрирование -> Обслуживание -> Обновление программы).
  2. Если обработка показывает статус «Ошибка», вы можете нажать кнопку «Повторить» для запуска выполнения отложенных заданий.
  3. В случае если система «зависла» в состоянии обновления, откройте регистр сведений СведенияОбОбновленииИБ (через «Все функции» / «Функции для технического специалиста») и вручную отредактируйте записи, переведя статус завершения обновления в значение Истина, либо воспользуйтесь внешней обработкой очистки результатов обновления из библиотеки стандартных подсистем (БСП).

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

← На главную