Как отслеживать ожидания на управляемых блокировках в 1С с помощью технологического журнала?

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

При администрировании высоконагруженных информационных баз 1С часто возникает задача мониторинга конкуренции за ресурсы. Нередко разработчики и администраторы ищут события наложения и снятия блокировок (по аналогии с Lock:Acquired и Lock:Released в MS SQL Server), чтобы вычислять длительность удержания ресурсов. Разберем, как устроен механизм логирования управляемых транзакционных блокировок в платформе 1С:Предприятие и как правильно настраивать технологический журнал для выявления задержек пользователей на блокировках без риска перегрузить рабочую систему.

Почему в технологическом журнале нет события снятия блокировки?

Проанализируем архитектуру управляемых блокировок в 1С. В отличие от пессимистических объектных блокировок, управляемые транзакционные блокировки подчиняются следующим правилам:

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

Как зафиксировать факт и время ожидания блокировки

Для сбора информации об ожиданиях нет необходимости вычислять дельту между установкой и снятием блокировки или искусственно занижать максимальное время ожидания (таймаут по умолчанию составляет 20 секунд). Платформа 1С фиксирует эти данные автоматически в событии TLOCK.

Рассмотрим ключевые особенности свойства Duration в событии TLOCK:

  1. Что показывает Duration: в событии TLOCK параметр Duration отражает не время удержания блокировки, а время ожидания освобождения ресурса текущим сеансом (в микросекундах).
  2. Мгновенный захват: если блокируемое пространство свободно, блокировка накладывается сразу, при этом Duration равен нулю или минимален, а свойство WaitConnections остается пустым.
  3. Конфликт сеансов: если ресурс уже занят другой транзакцией, поток переходит в режим ожидания. В случае успешного освобождения ресурса до истечения таймаута формируется событие TLOCK, где Duration покажет точное время простоя в очереди, а в WaitConnections будет указан номер сеанса-виновника.
  4. Превышение таймаута: если за 20 секунд ресурс так и не освободился, вместо TLOCK генерируется событие TTIMEOUT. В случае взаимной блокировки двух и более сеансов формируется событие TDEADLOCK.

Настройка технологического журнала для сбора ожиданий на продакшене

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

Посмотрим на пример конфигурационного файла logcfg.xml:


<?xml version="1.0" encoding="UTF-8"?>
<config xmlns="http://v8.1c.ru/v8/tech-log">
    <log location="C:\LOGS\TLOCK_WAIT" history="72">
        <event>
            <eq property="name" value="TLOCK"/>
            <gt property="duration" value="1000000"/>
        </event>
        <event>
            <eq property="name" value="TTIMEOUT"/>
        </event>
        <event>
            <eq property="name" value="TDEADLOCK"/>
        </event>
        <property name="all"/>
    </log>
</config>

Разберем параметры этой настройки:

  1. Фильтр по duration: условие <gt property="duration" value="1000000"/> отбирает только те события TLOCK, в которых пользователь ждал освобождения блокировки более 1 секунды (1 000 000 мкс).
  2. Альтернативный фильтр: можно использовать условие <ne property="WaitConnections" value=""/>, чтобы фиксировать абсолютно все случаи ожидания независимо от их длительности.
  3. События TTIMEOUT и TDEADLOCK: логируются без условий по длительности, так как они всегда свидетельствуют об исключительных ситуациях и ошибках для пользователей.

Методика поиска причины длительного удержания транзакции

Выясним причину долгого ожидания по шагам, используя полученный лог:

  1. В событии TLOCK или TTIMEOUT определяем номер блокирующего сеанса в свойстве WaitConnections, а также пространство блокировки в свойстве Regions и заблокированные поля в свойстве Locks.
  2. Находим события сеанса-виновника во временном интервале непосредственно перед моментом ожидания. Для этого можно включить сбор контекстов CALL, SCALL и запросов SDBL или DBMSSQL/DBPOSTGRS.
  3. Анализируем код транзакции, удерживающей ресурс: частыми причинами являются наложение управляемой блокировки в самом начале длительной процедуры, выполнение внутри транзакции тяжелых запросов к базе данных или обращение к внешним веб-сервисам.
  4. Оптимизируем код: сокращаем время транзакции, переносим блокировку ближе к моменту записи (например, непосредственно перед вызовом Записать()) и выносим некритичные операции за пределы транзакционного блока.
← На главную