Почему управляемые блокировки 1С не видны в sys.dm_tran_locks в MS SQL Server?

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

При переходе к изучению транзакционных механизмов и оптимизации многопользовательской работы в среде "1С:Предприятие" разработчики часто сталкиваются с неочевидным поведением системы. Типичный сценарий: мы пишем код, который явно накладывает исключительную блокировку на элемент справочника, запускаем транзакцию, пытаемся изменить этот элемент из другого сеанса и получаем закономерную ошибку "Превышено максимальное время ожидания блокировки". Казалось бы, блокировка работает. Однако при попытке проанализировать состояние СУБД через системное представление sys.dm_tran_locks в MS SQL Server мы обнаруживаем там пустоту — никаких блокировок на уровне строк или таблиц, кроме стандартной блокировки базы данных DATABASE.

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

Анализируем тестовый код: как создается блокировка

Рассмотрим по шагам программный код, который использовался для демонстрации проблемы:


НачатьТранзакцию();
БлокировкаДанных = Новый БлокировкаДанных;
ЭлементБлокировкиДанных = БлокировкаДанных.Добавить("Справочник.Спр1");
ЭлементБлокировкиДанных.УстановитьЗначение("Ссылка", Справочники.Спр1.НайтиПоНаименованию("Тест"));
ЭлементБлокировкиДанных.Режим = РежимБлокировкиДанных.Исключительный;
БлокировкаДанных.Заблокировать();
Предупреждение("Пока открыто это предупреждение, элемент справочника заблокирован");

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

  1. Открывается транзакция с помощью метода НачатьТранзакцию().
  2. Создается объект типа БлокировкаДанных.
  3. В пространство блокировок добавляется конкретное пространство — элемент справочника "Спр1" с отбором по конкретной ссылке.
  4. Устанавливается РежимБлокировкиДанных.Исключительный.
  5. Метод Заблокировать() накладывает блокировку.

Когда второй сеанс пытается изменить этот же элемент справочника, платформа 1С блокирует выполнение его транзакции, а через 20 секунд (стандартный тайм-аут по умолчанию) возвращает ошибку. Блокировка реально существует и отрабатывает. Но почему ее не видит MS SQL Server?

Почему СУБД "не видит" программный код 1С?

Основная причина кроется в самом определении и архитектуре управляемых блокировок (Managed Locks). Управляемые блокировки — это полностью виртуальный, программный механизм, который реализуется силами самого сервера приложений "1С:Предприятие" (конкретно процессами кластера, такими как rphost). Он функционирует на уровне бизнес-логики платформы.

Выясним, как это работает изнутри:

Как управляемый режим меняет поведение MS SQL (уровень изоляции RCSI)

Проанализируем, почему в современном режиме работы 1С физические блокировки в SQL при чтении стали редкостью. Начиная с версии платформы 8.2, основным и рекомендуемым режимом работы является управляемый режим блокировок.

При переводе базы данных в управляемый режим платформа принудительно включает на уровне MS SQL Server режим изоляции Read Committed Snapshot Isolation (RCSI) (чтение согласованных данных по моментальному снимку). Это кардинально меняет логику взаимодействия с СУБД:

  1. Отсутствие S-блокировок при чтении: В классическом режиме СУБД (автоматическом режиме блокировок 1С) при чтении данных накладывались разделяемые блокировки (S-блокировки). Они конфликтовали с исключительными блокировками (X-блокировками) пишущих транзакций. В режиме RCSI при чтении данных S-блокировки в SQL вообще не накладываются! Вместо этого СУБД читает старую, согласованную версию строки из базы tempdb (версионное хранилище).
  2. Параллелизм работы: Благодаря RCSI пишущие пользователи больше не блокируют читающих, а читающие — пишущих. Это колоссально увеличивает пропускную способность системы.
  3. Защита бизнес-логики: Поскольку СУБД больше не блокирует данные при чтении, возникает риск логических ошибок (например, классическая проблема "списания в минус"). Если два пользователя одновременно прочитают остаток товара "10 шт." и попытаются списать по "6 шт.", то без дополнительных мер оба документа проведутся, и остаток уйдет в "-2". Чтобы этого не произошло, разработчик 1С обязан явно накладывать управляемую блокировку БлокировкаДанных перед чтением остатков. Менеджер блокировок сервера 1С сам проверит пересечение по ресурсам и приостановит выполнение второго сеанса еще на уровне сервера приложений, даже не отправляя тяжелых запросов в СУБД.

Когда блокировки всё же появляются в СУБД?

Давайте разберем, при каких условиях мы все-таки сможем увидеть записи в системной таблице sys.dm_tran_locks MS SQL Server.

Физические блокировки на уровне СУБД появляются только тогда, когда транзакция начинает выполнять реальные изменения в базе данных или когда используются устаревшие механизмы работы:

Практический эксперимент: фиксируем блокировки в MS SQL

Посмотрим на практике, как можно увидеть реальное появление блокировок в SQL Server. Для этого нам необходимо совместить управляемую блокировку с физическим изменением данных.

Выполним следующие шаги:

  1. Создадим тестовый документ, при проведении которого будет происходить запись в регистр сведений или накопления.
  2. В модуле проведения документа (обработка проведения) напишем код записи данных и установим точку останова в самом конце процедуры, перед завершением транзакции проведения.
  3. Запустим проведение документа. Платформа начнет транзакцию, наложит управляемые блокировки, выполнит SQL-запросы на запись (UPDATE/INSERT) и остановится на точке останова. Транзакция в SQL останется открытой!
  4. Откроем SQL Server Management Studio (SSMS) и выполним запрос к системному представлению:

SELECT 
    request_session_id AS Spid,
    resource_type AS ResourceType,
    resource_database_id AS DatabaseId,
    request_mode AS LockType,
    request_status AS Status
FROM sys.dm_tran_locks
WHERE resource_database_id = DB_ID('ИмяВашейБазыДанных');

В результатах запроса мы гарантированно увидим не только блокировки типа DATABASE, но и блокировки типов PAGE (страница), KEY (ключ/строка индекса) или RID (идентификатор строки), со статусом GRANT и типом X (исключительная) или IX (намеренная исключительная). Это и есть те самые физические блокировки СУБД, которые удерживают измененные данные до момента завершения транзакции.

Как правильно мониторить управляемые блокировки 1С

Поскольку анализировать управляемые блокировки через средства СУБД невозможно, рассмотрим основные инструменты, которые позволяют разработчику и администратору 1С контролировать этот процесс в реальном времени.

1. Настройка Технологического Журнала (ТЖ) 1С

Технологический журнал — это самый мощный и детальный инструмент для анализа работы платформы. Для расследования проблем с управляемыми блокировками в конфигурационном файле logcfg.xml необходимо настроить сбор следующих ключевых событий:

2. Использование Центра управления производительностью (ЦУП)

Для крупных внедрений ручной анализ логов ТЖ может быть трудоемким. В таких случаях мы рекомендуем использовать ЦУП (Центр управления производительностью), входящий в состав корпоративного инструментального пакета "1С:КИП". ЦУП позволяет:

3. Внешние системы мониторинга

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

Резюме и рекомендации

Подводя итоги нашего разбора, сформулируем ключевые правила для работы с блокировками в 1С:

← На главную