При оптимизации высоконагруженных информационных систем и расследовании конфликтов параллельного доступа разработчики часто задаются вопросом: где физически располагается информация о блокировках? Нередко возникает путаница между объектными блокировками редактирования, управляемыми транзакционными блокировками платформы и физическими блокировками таблиц на стороне СУБД. Разберем детально архитектуру подсистемы блокировок платформы 1С:Предприятие 8.3, выясним места их хранения и рассмотрим практические методы их мониторинга.
Прежде чем определять место хранения, разделим блокировки на три принципиально разные категории, так как каждая из них обрабатывается собственным компонентом системы:
Рассмотрим механизм объектных блокировок. Когда пользователь открывает форму документа или элемента справочника на редактирование либо в программном коде вызывается метод ЗаблокироватьДанныеДляРедактирования(), платформа регистрирует объектную блокировку.
Многие ошибочно полагают, что эти сведения записываются в таблицы СУБД или сбрасываются в файл контекста сеанса snccntx.dat. На самом деле пессимистические блокировки располагаются исключительно в оперативной памяти процесса менеджера кластера серверов 1С (rmngr) в рамках специализированного «Сервиса блокировки объектов».
Выделим ключевые особенности их хранения:
Посмотрим на пример перехвата объектной блокировки в коде, когда требуется программно определить занятость объекта:
Попытка
ЗаблокироватьДанныеДляРедактирования(СсылкаНаДокумент);
Исключение
Информация = ОписаниеОшибки();
// Платформа вернет подробное описание с именем пользователя, заблокировавшего объект
ВызватьИсключение "Объект заблокирован пользователем: " + Информация;
КонецПопытки;
Проанализируем второй вид блокировок — управляемые транзакционные блокировки. Они создаются либо неявно (при записи объектов и наборов записей конфигурации, для которых установлен режим Управляемый), либо явно с помощью программного объекта БлокировкаДанных внутри открытой транзакции.
Место их расположения — оперативная память сервиса транзакционных блокировок кластера 1С (процесс rmngr). Сервер СУБД ничего не знает о логических пространствах управляемых блокировок 1С. Менеджер кластера ведет в ОЗУ собственные таблицы соответствий пространств имен, полей и диапазонов значений.
Разберем пример явной установки управляемой блокировки с использованием объекта БлокировкаДанных:
Блокировка = Новый БлокировкаДанных;
ЭлементБлокировки = Блокировка.Добавить("РегистрНакопления.ОстаткиТоваров");
ЭлементБлокировки.Режим = РежимБлокировкиДанных.Исключительный;
ЭлементБлокировки.УстановитьЗначение("Склад", ВыбранныйСклад);
ЭлементБлокировки.ИсточникДанных = ТаблицаТоваров;
ЭлементБлокировки.ИспользоватьПоляИзИсточникаДанных("Номенклатура", "Товар");
НачатьТранзакцию();
Попытка
Блокировка.Заблокировать();
// Выполнение движений и проверок
ЗафиксироватьТранзакцию();
Исключение
ОтменитьТранзакцию();
ВызватьИсключение;
КонецПопытки;
Обратите внимание: данные управляемой блокировки являются строго транзиентными. Они существуют только в момент выполнения транзакции. В случае вызова ЗафиксироватьТранзакцию() или ОтменитьТранзакцию() менеджер кластера мгновенно удаляет соответствующие структуры из оперативной памяти.
Выясним, какую роль играет сам сервер баз данных. Если в свойствах конфигурации выбран Автоматический режим управления блокировкой данных, система 1С полностью перекладывает контроль параллелизма на СУБД. В этом режиме при начале транзакции выставляются высокие уровни изоляции (Serializable/Repeatable Read).
В таком сценарии блокировки формируются и хранятся в оперативной памяти самой СУБД (пул блокировок в MS SQL Server или разделяемая память shared_buffers в PostgreSQL). Сервер 1С не имеет внутреннего реестра этих блокировок: он лишь отправляет SQL-запросы и в случае конфликта получает ошибку превышения времени ожидания от СУБД.
При работе в режиме Управляемый платформа снижает уровень изоляции транзакций на уровне СУБД до Read Committed (в MS SQL Server рекомендуется режим Read Committed Snapshot Isolation — RCSI). Это позволяет читать данные без наложения блокировок на уровне СУБД, а всю конкуренцию за данные берет на себя менеджер транзакционных блокировок 1С.
Поскольку блокировки распределены между оперативной памятью кластера 1С и памятью СУБД, для их анализа применяются специализированные средства:
TLOCK, TTIMEOUT и TDEADLOCK. Событие TLOCK позволяет увидеть заблокированные пространства (параметр Regions), значения отборов (Locks) и номер соединения, удерживающего блокировку (WaitConnections). Включение свойств Context и p:processName дает возможность выявить точную строку исходного кода, спровоцировавшую ожидание.rac или COM-интерфейс администрирования вызовом метода GetLocks().sys.dm_tran_locks и sys.dm_os_waiting_tasks, а в PostgreSQL — таблицы pg_locks и pg_stat_activity.Таким образом, в клиент-серверной архитектуре 1С 8.3 блокировки не сохраняются в служебных файлах сеансов на жестком диске. Они удерживаются исключительно в оперативной памяти: логические (объектные и управляемые) — в процессе rmngr сервера 1С, а физические транзакционные — в памяти используемой СУБД.