При работе с высоконагруженными или «тяжелыми» документами в системе 1С:Предприятие программисты часто сталкиваются с необходимостью управления доступом к данным. Одним из ключевых инструментов здесь является метод Заблокировать(). В этой статье мы подробно разберем, как работает этот механизм, какие блокировки он вызывает и чем отличается от транзакционных блокировок СУБД.
Давайте проанализируем ситуацию: когда пользователь открывает форму документа для редактирования, система должна гарантировать, что другой пользователь не сможет изменить этот же документ одновременно. Метод ЭтотОбъект.Заблокировать() реализует так называемую пессимистическую блокировку. Рассмотрим подробнее, что это значит.
В отличие от оптимистической блокировки, которая проверяет версию объекта только в момент записи, пессимистическая блокировка «захватывает» объект сразу. Это позволяет оповестить других пользователей о том, что данные уже редактируются. Таким образом, это не столько механизм защиты целостности базы данных (за это отвечают транзакции), сколько механизм взаимодействия и оповещения пользователей.
Важные особенности объектной блокировки:
rmngr), а не на уровне SQL-сервера.Разблокировать().Отвечая на вопрос автора темы, выясним причину: вызывает ли этот метод блокировки? Да, вызывает, но это специфический вид блокировок. У объектных блокировок есть свой собственный менеджер, который работает параллельно с менеджером управляемых транзакционных блокировок.
Рассмотрим, к чему приводит вызов ЭтотОбъект.Заблокировать():
ДокументОбъект), попытавшиеся выполнить этот же метод для того же идентификатора (GUID), получат отказ.Посмотрим на пример кода, который часто встречается в типовых и самописных конфигурациях при открытии формы документа. Разберем по шагам, как правильно обрабатывать захват объекта:
// Проверка получения монопольного доступа на редактирование
Попытка
ЭтотОбъект.Заблокировать();
Исключение
// Если заблокировать не удалось, выводим сообщение пользователю
ТекстОшибки = ОписаниеОшибки();
Сообщить("Не удалось заблокировать объект для редактирования. " + ТекстОшибки);
// Здесь можно установить флаг "ТолькоПросмотр" для формы
КонецПопытки;
Проанализируем этот фрагмент. Использование конструкции Попытка...Исключение — это практически единственный надежный способ узнать, занят ли объект кем-то другим. В блоке Исключение через функцию ОписаниеОшибки() можно получить строку, в которой платформа услужливо указывает имя пользователя, захватившего данные, и время начала блокировки.
Многие начинающие разработчики совершают ошибку, пытаясь использовать метод Заблокирован() для проверки доступности объекта. Выясним, почему это не работает так, как ожидается. Рассмотрим определение этого метода в синтакс-помощнике: он возвращает Истина, только если объект заблокирован текущим программным объектом в текущем сеансе.
Почему Заблокирован() бесполезен для поиска чужих блокировок:
Заблокирован() для этого же документа вернет Ложь.В современном управляемом приложении за пессимистическую блокировку часто отвечает свойство формы Автоблокировка. Если оно включено, платформа сама вызывает аналогичные механизмы при начале изменения данных в форме. Однако иногда требуется более тонкий контроль. Разберем метод, который используется в управляемых формах:
// В контексте управляемой формы
Попытка
ЗаблокироватьДанныеФормыДляРедактирования();
Исключение
// Обработка случая, когда форма уже редактируется другим пользователем
КонецПопытки;
Этот метод работает аналогично Заблокировать() для объектов, но адаптирован под специфику работы управляемого интерфейса и клиент-серверного взаимодействия.
Нам важно понимать жизненный цикл объектной блокировки, чтобы не плодить «зависшие» захваты данных. Проанализируем ситуации, при которых блокировка, установленная через Заблокировать(), прекращает свое действие:
Разблокировать() в коде.Неопределено).Возвращаясь к вопросу о «тормознутом» документе, стоит отметить, что сами по себе объектные блокировки крайне легковесны. Они не нагружают дисковую подсистему СУБД и не вызывают взаимоблокировок (deadlocks) на уровне SQL.
Однако, если в коде формы при каждом открытии или при каждом изменении реквизита происходит обращение к Заблокировать(), это создает дополнительные сетевые вызовы между рабочим процессом (rphost) и менеджером кластера (rmngr). В условиях медленной сети или перегруженного сервера это может ощущаться как микрозадержки при работе с интерфейсом.
Подведем итог: метод Заблокировать() — это мощный инструмент для управления совместной работой пользователей. Он вызывает специфические объектные блокировки в памяти сервера. Для эффективной работы с ним всегда используйте конструкцию Попытка...Исключение и помните, что метод Заблокирован() не поможет вам определить захват данных другим пользователем.