Почему в консоли 1С растет показатель «Захвачено СУБД» и как освободить соединение?

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

При администрировании кластера серверов 1С многие специалисты сталкиваются с ситуацией, когда в консоли администрирования у определенных сеансов начинает неуклонно расти показатель «Захвачено СУБД». Особенно странно это выглядит, когда пользователь в данный момент не выполняет никаких активных действий, а журнал регистрации не фиксирует тяжелых запросов. Разберем детально, что означает этот показатель, почему он растет и как правильно оптимизировать код, чтобы избежать дефицита соединений в пуле.

Что на самом деле означает показатель «Захвачено СУБД»

Для начала проанализируем определение из документации. Многие ошибочно полагают, что этот параметр указывает на блокировку данных в таблицах базы. На самом деле, речь идет о захвате физического соединения из пула соединений рабочего процесса rphost к серверу баз данных (MS SQL, PostgreSQL и др.).

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

Согласно стандартам платформы, захват соединения происходит в трех случаях:

  1. Выполняется активный вызов СУБД (запрос, запись данных).
  2. Открыта транзакция (явно или неявно).
  3. Удерживается объект МенеджерВременныхТаблиц, в котором создана хотя бы одна временная таблица.

Причина №1: Жизненный цикл Менеджера временных таблиц

Как показывает практика и обсуждение специалистов, наиболее частой причиной длительного захвата соединения является использование объекта МенеджерВременныхТаблиц (МВТ). Выясним, почему это происходит. Временные таблицы физически создаются в базе данных (в tempdb для MS SQL). Чтобы платформа могла обратиться к ним в следующем запросе в рамках того же сеанса, она обязана удерживать контекст соединения.

Проанализируем типичную ошибку: программист создает МВТ, наполняет его данными, но не уничтожает таблицы и не закрывает менеджер явно. Рассмотрим сценарий, при котором соединение будет «висеть»:

Пока объект МенеджерВременныхТаблиц «жив» в памяти сервера приложений и содержит хотя бы одну таблицу, показатель «Захвачено СУБД» будет расти. Соединение освободится только при закрытии формы или завершении сеанса, что может затянуться на часы и даже сутки.

Как правильно освобождать ресурсы в коде

Разберем методы, которые гарантированно решают проблему «вечного» захвата соединения. Недостаточно просто вызвать команду УНИЧТОЖИТЬ в тексте запроса. Хотя это очистит данные в СУБД, сам объект МВТ может продолжать удерживать связь.

Посмотрим на пример правильной структуры кода при работе с временными таблицами:


МенеджерВТ = Новый МенеджерВременныхТаблиц;
Запрос = Новый Запрос;
Запрос.МенеджерВременныхТаблиц = МенеджерВТ;

Попытка
    Запрос.Текст = 
    "ВЫБРАТЬ Ссылка ИЗ Справочник.Номенклатура ПОМЕСТИТЬ ВТ_Данные";
    Запрос.Выполнить();
    
    // ... дальнейшая логика обработки ...
    
    // Обязательное уничтожение таблиц, когда они больше не нужны
    Запрос.Текст = "УНИЧТОЖИТЬ ВТ_Данные";
    Запрос.Выполнить();
Исключение
    // Обработка ошибок
    ЗаписьЖурналаРегистрации("Ошибка обработки ВТ", УровеньЖурналаРегистрации.Ошибка);
КонецПопытки;

// Критически важный шаг для освобождения соединения СУБД
МенеджерВТ.Закрыть(); 

Метод Закрыть() принудительно разрывает связь объекта с соединением СУБД. Даже если переменная МенеджерВТ останется в памяти (например, как реквизит формы), показатель в консоли перестанет расти, так как соединение вернется в пул.

Причина №2: «Забытые» транзакции

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

Это крайне опасная ситуация, так как на стороне SQL-сервера такая транзакция имеет статус sleeping, но при этом она остается открытой. Это препятствует очистке лога транзакций (LDF-файла) и может привести к переполнению дискового пространства.

Причина №3: Особенности динамических списков

Проанализируем еще один нюанс, характерный для платформы 1С. В некоторых версиях (особенно 8.3.9–8.3.11) динамические списки с произвольными запросами, использующими временные таблицы, могли провоцировать длительный захват СУБД. Если включен режим «Динамическое считывание данных», платформа может удерживать соединение для поддержания курсора выборки. В таких случаях рекомендуется пересмотреть запрос динамического списка, стараясь избегать сложных конструкций с ПОМЕСТИТЬ внутри основного запроса списка.

Диагностика с помощью Технологического журнала

Если визуальный анализ кода не дает результатов, воспользуемся инструментом Технологический журнал (ТЖ). Чтобы точно определить, какой именно запрос или объект удерживает соединение, настроим сбор событий DBMSSQL (или DBV8DBEng для других СУБД).

В настройках ТЖ следует обратить внимание на длительность событий. Мы ищем ситуацию, где зафиксировано начало операции с СУБД, но отсутствует событие возврата соединения в пул. В тексте события ТЖ мы увидим конкретный SQL-запрос, который создал временную таблицу. Это позволит нам мгновенно найти проблемное место в конфигурации 1С по тексту запроса.

Подведем итоги

Рост показателя «Захвачено СУБД» — это всегда сигнал к проведению технического аудита кода. Для предотвращения проблем с производительностью рекомендуем придерживаться следующих правил:

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

← На главную