При переходе к изучению транзакционных механизмов и оптимизации многопользовательской работы в среде "1С:Предприятие" разработчики часто сталкиваются с неочевидным поведением системы. Типичный сценарий: мы пишем код, который явно накладывает исключительную блокировку на элемент справочника, запускаем транзакцию, пытаемся изменить этот элемент из другого сеанса и получаем закономерную ошибку "Превышено максимальное время ожидания блокировки". Казалось бы, блокировка работает. Однако при попытке проанализировать состояние СУБД через системное представление sys.dm_tran_locks в MS SQL Server мы обнаруживаем там пустоту — никаких блокировок на уровне строк или таблиц, кроме стандартной блокировки базы данных DATABASE.
Давайте подробно разберем, почему так происходит, как взаимосвязаны управляемые блокировки 1С и транзакции на уровне СУБД, а также научимся правильно отслеживать и расследовать подобные ситуации.
Рассмотрим по шагам программный код, который использовался для демонстрации проблемы:
НачатьТранзакцию();
БлокировкаДанных = Новый БлокировкаДанных;
ЭлементБлокировкиДанных = БлокировкаДанных.Добавить("Справочник.Спр1");
ЭлементБлокировкиДанных.УстановитьЗначение("Ссылка", Справочники.Спр1.НайтиПоНаименованию("Тест"));
ЭлементБлокировкиДанных.Режим = РежимБлокировкиДанных.Исключительный;
БлокировкаДанных.Заблокировать();
Предупреждение("Пока открыто это предупреждение, элемент справочника заблокирован");
В этом фрагменте мы видим классическую последовательность действий для управляемого режима блокировок:
НачатьТранзакцию().БлокировкаДанных.РежимБлокировкиДанных.Исключительный.Заблокировать() накладывает блокировку.Когда второй сеанс пытается изменить этот же элемент справочника, платформа 1С блокирует выполнение его транзакции, а через 20 секунд (стандартный тайм-аут по умолчанию) возвращает ошибку. Блокировка реально существует и отрабатывает. Но почему ее не видит MS SQL Server?
Основная причина кроется в самом определении и архитектуре управляемых блокировок (Managed Locks). Управляемые блокировки — это полностью виртуальный, программный механизм, который реализуется силами самого сервера приложений "1С:Предприятие" (конкретно процессами кластера, такими как rphost). Он функционирует на уровне бизнес-логики платформы.
Выясним, как это работает изнутри:
_Reference50), строками и индексами. СУБД абсолютно ничего не знает о метаданных 1С: о том, что такое "Справочник.Спр1", какова его структура и какой конкретно элемент соответствует ссылке в памяти 1С.НачатьТранзакцию(), платформа действительно отправляет в SQL команду BEGIN TRANSACTION. На уровне СУБД открывается транзакция. Ей присваивается идентификатор, и накладывается блокировка типа DATABASE (что мы и видим в sys.dm_tran_locks). Но так как физических запросов на чтение или запись данных в СУБД еще не поступало, СУБД считает транзакцию "пустой" и не накладывает никаких блокировок на таблицы или строки.Проанализируем, почему в современном режиме работы 1С физические блокировки в SQL при чтении стали редкостью. Начиная с версии платформы 8.2, основным и рекомендуемым режимом работы является управляемый режим блокировок.
При переводе базы данных в управляемый режим платформа принудительно включает на уровне MS SQL Server режим изоляции Read Committed Snapshot Isolation (RCSI) (чтение согласованных данных по моментальному снимку). Это кардинально меняет логику взаимодействия с СУБД:
tempdb (версионное хранилище).БлокировкаДанных перед чтением остатков. Менеджер блокировок сервера 1С сам проверит пересечение по ресурсам и приостановит выполнение второго сеанса еще на уровне сервера приложений, даже не отправляя тяжелых запросов в СУБД.Давайте разберем, при каких условиях мы все-таки сможем увидеть записи в системной таблице sys.dm_tran_locks MS SQL Server.
Физические блокировки на уровне СУБД появляются только тогда, когда транзакция начинает выполнять реальные изменения в базе данных или когда используются устаревшие механизмы работы:
Записать() или Удалить() для любого объекта (документа, справочника, набора записей регистра), платформа генерирует SQL-запросы типа INSERT, UPDATE или DELETE. В этот момент СУБД MS SQL Server обязана гарантировать физическую целостность и незамедлительно накладывает монопольные исключительные блокировки (X-блокировки) на изменяемые строки, а также намеренные блокировки (IX) на страницы и таблицы.sys.dm_tran_locks, но платой за это станет низкая производительность и частые взаимоблокировки (дедлоки).Посмотрим на практике, как можно увидеть реальное появление блокировок в SQL Server. Для этого нам необходимо совместить управляемую блокировку с физическим изменением данных.
Выполним следующие шаги:
UPDATE/INSERT) и остановится на точке останова. Транзакция в SQL останется открытой!
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С
Технологический журнал — это самый мощный и детальный инструмент для анализа работы платформы. Для расследования проблем с управляемыми блокировками в конфигурационном файле logcfg.xml необходимо настроить сбор следующих ключевых событий:
TLOCK — данное событие регистрирует все факты установки, снятия и успешного ожидания управляемых блокировок на сервере 1С. По нему можно понять, какие именно пространства блокировок занимали сеансы.TTIMEOUT — критически важное событие. Оно фиксирует ошибку превышения времени ожидания блокировки. В логах этого события детально расписывается: какой сеанс пострадал ("жертва"), какой сеанс держал блокировку и не отпускал ее ("виновник"), а также приводится полный контекст (стек вызова кода 1С), приведший к этой ситуации.TDEADLOCK — фиксирует возникновение взаимных управляемых блокировок (когда Сеанс 1 ждет Сеанс 2, а Сеанс 2 ждет Сеанс 1).2. Использование Центра управления производительностью (ЦУП)
Для крупных внедрений ручной анализ логов ТЖ может быть трудоемким. В таких случаях мы рекомендуем использовать ЦУП (Центр управления производительностью), входящий в состав корпоративного инструментального пакета "1С:КИП". ЦУП позволяет:
3. Внешние системы мониторинга
Также существуют специализированные внешние сервисы и парсеры ТЖ, которые собирают информацию о блокировках и визуализируют ее в удобных дашбордах. Они позволяют оперативно получать уведомления на почту или в мессенджеры в случае лавинообразного роста числа таймаутов на сервере.
Подводя итоги нашего разбора, сформулируем ключевые правила для работы с блокировками в 1С:
sys.dm_tran_locks) — их там нет и быть не может, так как они живут исключительно в оперативной памяти сервера приложений 1С.TLOCK, TTIMEOUT, TDEADLOCK) или специализированные инструменты мониторинга (ЦУП).