sp_getapplock (Transact-SQL)

Применимо к:SQL Server База данных SQL Azure Управляемый экземпляр SQL Azure

Размещает блокировку на ресурсе приложения.

Соглашения о синтаксисе Transact-SQL

Синтаксис

  
sp_getapplock [ @Resource = ] 'resource_name' ,  
     [ @LockMode = ] 'lock_mode'   
     [ , [ @LockOwner = ] 'lock_owner' ]   
     [ , [ @LockTimeout = ] 'value' ]  
     [ , [ @DbPrincipal = ] 'database_principal' ]  
[ ; ]  

Аргументы

[ ] @Resource= 'resource_name'
Строка, указывающая имя, которое определяет ресурс блокировки. Приложение должно гарантировать уникальность имени ресурса. Указанное имя хэшируется внутренне в значение, которое может храниться в диспетчере блокировки SQL Server. resource_name — nvarchar(255) без значения по умолчанию. Если строка ресурса длиннее nvarchar(255), она будет усечена до nvarchar(255).

resource_name является двоичным по сравнению, поэтому учитывает регистр независимо от параметров сортировки текущей базы данных.

Примечание.

После того как произойдет блокировка приложения, только первые 32 символа могут быть получены в виде обычного текста; остаток будет хэширован.

[ ] @LockMode= 'lock_mode'
Надо ли получить режим блокировки для указанного ресурса. lock_mode — varchar(32) и не имеет значения по умолчанию. Это значение может быть любым из следующих значений: Shared, Update, IntentShared, IntentExclusive или Exclusive. Дополнительные сведения см. в режимах блокировки.

[ ] @LockOwner= 'lock_owner'
Владелец блокировки, которая имеет значение lock_owner на момент запроса блокировки. lock_owner — varchar(32). Значением может быть Transaction (по умолчанию) или Session. Если значение lock_ownerТранзакция, по умолчанию или указано явно, sp_getapplock необходимо выполнить из транзакции.

[ ] @LockTimeout= 'value'
Значение времени ожидания блокировки (в миллисекундах). Значение по умолчанию совпадает со значением, возвращаемым @@LOCK_TIMEOUT. Значение -1 (по умолчанию) указывает на отсутствие времени ожидания (то есть инструкция будет ждать всегда). Чтобы указать, что запрос на блокировку должен возвращать возвращаемый код -1 вместо ожидания блокировки, когда запрос не может быть предоставлен немедленно, укажите 0.

[ ] @DbPrincipal= 'database_principal'
Пользователь, роль или роль приложения, которые имеют разрешения на объект базы данных. Вызывающий объект функции должен быть членом database_principal, dbo или предопределенной ролью базы данных db_owner для успешного вызова функции. Значение по умолчанию: public.

Значения кода возврата

>= 0 (успешно) или < 0 (сбой)

Значение Результат
0 Блокировка была успешно предоставлена в синхронном режиме.
1 Блокировка была предоставлена успешно после снятия других несовместимых блокировок.
-1 Истекло время ожидания запроса блокировки.
-2 Запрос блокировки был отменен.
-3 Запрос блокировки был выбран как жертва взаимоблокировки.
-999 Указывает ошибку при проверке параметра или другую ошибку вызова.

Замечания

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

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

  • Идентификатор базы данных, содержащей ресурс блокировки.

  • Субъект базы данных, указанный в параметре @DbPrincipal .

  • Имя блокировки, указанное в параметре @Resource.

Только элемент участника базы данных, указанного в параметре @DbPrincipal, может запросить блокировки приложений, которые определяют этого участника. Члены ролей dbo и db_owner косвенно являются членами всех ролей.

Блокировки могут быть сняты явно с помощью процедуры sp_releaseapplock. Если приложение вызывает процедуру sp_getapplock несколько раз для одного и того же ресурса блокировки, то процедура sp_releaseapplock должна вызываться такое же количество раз для снятия блокировки. При открытии блокировки с Transaction владельцем блокировки эта блокировка освобождается при фиксации или откате транзакции.

Если процедура sp_getapplock вызывается несколько раз для одного и того же ресурса блокировки, но режим блокировки, указанный в каком-либо запросе, отличается от существующего режима, на ресурс действует объединение двух режимов блокировки. В большинстве случаев это значит, что режим блокировки повышается до более сильного режима блокировки, до существующего режима или до заново запрашиваемого режима. Этот более сильный режим блокировки удерживается до тех пор, пока блокировка в конечном итоге не будет освобождена. Например, в следующей последовательности вызовов ресурс удерживается в режиме Exclusive, а не в режиме Shared.

USE AdventureWorks2022;  
GO  
BEGIN TRANSACTION;  
DECLARE @result int;  
EXEC @result = sp_getapplock @Resource = 'Form1',   
               @LockMode = 'Shared';  
EXEC @result = sp_getapplock @Resource = 'Form1',   
               @LockMode = 'Exclusive';  
EXEC @result = sp_releaseapplock @Resource = 'Form1';  
COMMIT TRANSACTION;  
GO  

Взаимоблокировка с блокировкой приложения не откатывает транзакцию, запросившую блокировку приложения. Любой откат, который может потребоваться как результат возвращаемого значения, должен быть сделан вручную. Следовательно, рекомендуется включить в код проверку на ошибки с тем, чтобы в случае возврата определенного значения (например -3) могла быть запущена инструкция ROLLBACK TRANSACTION или предпринято другое действие.

Рассмотрим пример:

USE AdventureWorks2022;  
GO  
BEGIN TRANSACTION;  
DECLARE @result int;  
EXEC @result = sp_getapplock @Resource = 'Form1',   
               @LockMode = 'Exclusive';  
IF @result = -3  
BEGIN  
    ROLLBACK TRANSACTION;  
END  
ELSE  
BEGIN  
    EXEC @result = sp_releaseapplock @Resource = 'Form1';  
    COMMIT TRANSACTION;  
END;  
GO  

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

Используйте динамическое представление управления sys.dm_tran_locks или системную хранимую процедуру sp_lock для проверки сведений о блокировке или использования SQL Server Profiler для мониторинга блокировок.

Разрешения

Требуется членство в роли public.

Примеры

Следующий пример помещает совмещаемую блокировку, связанную с текущей транзакцией, на ресурс Form1 в базе данных AdventureWorks2022.

USE AdventureWorks2022;  
GO  
BEGIN TRAN;  
DECLARE @result int;  
EXEC @result = sp_getapplock @Resource = 'Form1',   
               @LockMode = 'Shared';  
COMMIT TRAN;  
GO  

В данном примере в качестве участника базы данных задается dbo.

BEGIN TRAN;  
EXEC sp_getapplock @DbPrincipal = 'dbo', @Resource = 'AdventureWorks2022',   
     @LockMode = 'Shared';  
COMMIT TRAN;  
GO  

См. также

APPLOCK_MODE (Transact-SQL)
APPLOCK_TEST (Transact-SQL)
sp_releaseapplock (Transact-SQL)