При выполнении тяжелых регламентных операций, таких как Закрытие месяца в конфигурации 1С:Управление производственным предприятием (УПП) 1.3, пользователи часто сталкиваются с пугающим сообщением: Ошибка при вызове метода контекста (Получить) по причине: В данной транзакции уже происходили ошибки!. Эта ситуация характерна тем, что программа указывает на строку кода, которая сама по себе может быть абсолютно корректной. Рассмотрим подробнее, почему это происходит и как найти истинного виновника сбоя.
Прежде всего, нам необходимо понять механику работы платформы 1С:Предприятие с транзакциями. Когда мы запускаем Закрытие месяца, программа открывает одну большую транзакцию, внутри которой выполняются сотни подзадач: расчет амортизации, распределение затрат, корректировка стоимости номенклатуры и т.д. Если в любой из этих подзадач происходит программная ошибка (например, деление на ноль, нехватка прав доступа или нарушение уникальности записей), транзакция помечается платформой как «битая» (rollback-only).
После этого любое последующее обращение к базе данных в рамках этой же транзакции будет вызывать сообщение В данной транзакции уже происходили ошибки. Проанализируем ситуацию: чаще всего ошибка «вылетает» в общем модуле РаботаСОбщимиПеременнымиПовтИсп. Это происходит потому, что код пытается прочитать какую-то константу или параметр из базы, чтобы продолжить работу, но база данных уже «заблокирована» из-за предыдущего сбоя.
Первым делом мы должны заглянуть в Журнал регистрации. Поскольку транзакция закрытия месяца длительная, истинная ошибка могла произойти за несколько секунд или даже минут до того, как появилось финальное окно с сообщением. Разберем порядок действий:
Ошибка.Если Журнал регистрации не дал четкого ответа, мы воспользуемся инструментами Конфигуратора. Нам нужно поймать момент самого первого сбоя. Рассмотрим, как настроить остановку по ошибке:
В Конфигураторе перейдем в меню Отладка — Остановка по ошибке. Здесь важно установить галочку «Останавливаться по ошибке». Однако, если программист в коде использовал конструкцию Попытка ... Исключение, обычная остановка может не сработать. В этом случае мы обязательно устанавливаем флаг «Останавливаться на исключениях, даже если они обрабатываются».
Запустим процесс закрытия месяца под отладкой. Когда возникнет ПЕРВАЯ ошибка (даже если она скрыта внутри Попытка), отладчик остановит выполнение. Именно это место в коде и будет причиной «поломки» транзакции.
Одной из самых частых причин возникновения обсуждаемой проблемы является некорректное использование обработки исключений в нетиповых (доработанных) конфигурациях. Проанализируем опасный фрагмент кода:
Попытка
ДокументОбъект.Записать(РежимЗаписиДокумента.Проведение);
Исключение
// Ошибка произошла, транзакция в БД уже «сломана»
Сообщить("Не удалось провести документ!");
// Код продолжает выполняться дальше, что и вызовет ошибку транзакции позже
КонецПопытки;
Если этот код выполняется внутри большой транзакции (например, при проведении «Закрытия месяца»), то после попадания в блок Исключение любая следующая попытка записи или чтения из БД приведет к нашей ошибке. Выясним, как это исправить: если вы используете Попытка внутри транзакции, вы обязаны либо прекратить выполнение, либо использовать оператор ВызватьИсключение, чтобы транзакция корректно откатилась целиком.
Иногда корень зла кроется в механизмах, которые работают «невидимо» для разработчика. В УПП 1.3 при записи любого документа срабатывают Подписки на события. Рассмотрим ситуацию: при проведении документа закрытия месяца система пытается зарегистрировать изменения в планах обмена (для выгрузки в Бухгалтерию или ЗУП).
Если в плане обмена повреждены узлы или правила регистрации содержат ошибки, произойдет сбой записи в таблицу регистрации изменений. Посмотрим на алгоритм проверки:
Как было замечено в обсуждении, ошибка часто проявляется в модулях с пометкой «Повторное использование возвращаемых значений». Платформа кэширует результаты функций этих модулей. Если транзакция прервана, кэш может вести себя непредсказуемо. Разберем способы очистки:
/ClearCache.Если ошибка возникает именно 15-го числа (как в исходном вопросе), это может быть связано с регламентными операциями по расчету себестоимости или партионному учету. Проанализируем настройки:
Проверим константу «Партионный учет бухгалтерский». В некоторых случаях установленная дата начала (например, 01.01.0001) заставляет программу пытаться восстановить последовательность с самого начала времен, что приводит к переполнению транзакционных логов или блокировкам в SQL. Также стоит проверить регистр сведений Настройки закрытия месяца на наличие противоречивых записей.
Резюмируем: Ошибка В данной транзакции уже происходили ошибки — это лишь симптом. Чтобы вылечить систему, мы должны найти «нулевого пациента» с помощью отладчика (настроенного на остановку по исключениям) и анализа Журнала регистрации. Помните, что в 90% случаев виноват некорректный блок Попытка...Исключение, который «проглотил» реальную ошибку, но оставил транзакцию в нерабочем состоянии.