Почему база 1С зависает при откате транзакции (Отказ = Истина) во время проведения документа?

Программист IT и автоматизация бизнеса
← На главную

Рассмотрим распространенную проблему, с которой сталкиваются разработчики при проектировании алгоритмов проведения документов в 1С. Ситуация выглядит следующим образом: при проведении документа база «зависает» в клиент-серверном варианте работы. При этом в файловой базе или на локальном сервере PostgreSQL этот же код выполняется без задержек.

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

Разберем причины зависания: откат транзакций в СУБД

При выходе из процедуры обработки проведения с установленным флагом Отказ = Истина платформа инициирует отмену (откат) транзакции. В файловом варианте транзакции реализуются на уровне внутренних блокировок файлов самой платформой 1С, поэтому откат происходит локально и очень быстро. В клиент-серверном же варианте 1С полностью делегирует управление транзакциями серверу СУБД (например, MS SQL Server).

В отличие от прямой записи данных, откат транзакции (Rollback) — это сложная и зачастую однопоточная операция для СУБД. Если алгоритм проведения генерирует большой объем движений (например, массивное списание или формирование множества комплектов), СУБД должна физически удалить эти вставленные данные и вернуть базу в исходное состояние, считывая информацию из журнала транзакций.

Откат может занимать в разы больше времени, чем сама запись. Сеанс пользователя визуально «зависает», ожидая ответа от сервера. Если дисковая подсистема, на которой лежит файл журнала транзакций (LDF), медленная или перегружена, возникают массовые ожидания на уровне СУБД, что полностью парализует текущую операцию.

Важно отметить различия между СУБД. В PostgreSQL используется архитектура многоверсионности (MVCC). При откате транзакции данные фактически не нужно «стирать» так же тяжело, как в MS SQL — версии строк просто помечаются как неактуальные. Этим объясняется то, что на локальном PostgreSQL подобное зависание может не воспроизводиться.

Решение 1: Правильная архитектура кода (Контроль остатков до записи)

Методика «сначала всё записать в базу, потом запросом проверить остатки и откатить транзакцию, если минус» считается антипаттерном при больших объемах данных из-за огромных накладных расходов на СУБД. Выясним, как правильно переписать алгоритм.

Предварительный контроль («Старая» методика 1С)

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

  1. Сначала заблокируем нужные записи регистра, используя объект БлокировкаДанных.
  2. Прочитаем текущие остатки скомпонованным запросом (с учетом данных самого документа, помещенных во временную таблицу).
  3. Проверим наличие дефицита (отрицательных остатков).
  4. Только если проверка пройдена успешно (остатков хватает), переходим к формированию и записи движений и комплектов.

При таком подходе никаких тяжелых откатов физически записанных данных в СУБД не потребуется, так как при нехватке остатков мы просто устанавливаем отказ еще до начала ресурсоемких операций вставки.

Расчет в оперативной памяти

Альтернативный вариант — сформировать комплекты и будущие движения в виде таблиц значений (или структур коллекций) в оперативной памяти сервера 1С. Затем провести расчет на основе виртуальных таблиц остатков. И лишь в самом конце, если все проверки пройдены, загрузить эти коллекции в набор записей регистра, например в Движения.ТоварыНаСкладах.

Решение 2: Диагностика и обслуживание СУБД MS SQL Server

Если изменить алгоритм быстро невозможно, или проблема проявляется даже при небольших объемах отменяемых данных, обратим внимание на настройки сервера баз данных.

  1. Проверка режима восстановления: Посмотрим свойства базы данных в Management Studio. Если установлен режим полного восстановления (Full Recovery Model), журнал транзакций может непрерывно расти. В этом случае необходимо проверить, как часто делаются бэкапы лога. При необходимости выполним обслуживание рабочей базы — сделаем усечение (шринк) журнала транзакций.
  2. Анализ дисковой подсистемы: Отследим ресурсоемкие сессии. Если проблема в медленных дисках — перенесем системную базу TempDB и файл журнала транзакций (LDF) на быстрые SSD/NVMe-накопители.
  3. Настройка авторасширения (Autogrowth): Убедимся, что шаг авторасширения файла журнала транзакций задан фиксированным значением (например, 512 МБ), а не в процентах. Это снизит задержки при необходимости СУБД выделить дополнительное место на диске во время тяжелых операций.
  4. Исключения антивируса: Проверим, что папки с файлами данных и логов SQL-сервера, а также рабочие каталоги сервера 1С (rphost) добавлены в исключения антивируса. При массовом откате движений антивирус может начать сканировать активно изменяемые файлы, вызывая катастрофические задержки.

Для точной диагностики на стороне 1С рекомендуем включить Технологический журнал и настроить сбор событий DBMSSQL, EXCP и TTIMEOUT. Это позволит точно увидеть, на каком именно SQL-запросе висит сервер во время выполнения возврата из обработки проведения.

← На главную