Поделиться через


sp_getapplock (Transact-SQL)

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

Значок ссылки на разделСинтаксические обозначения в 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 имеет тип nvarchar(32) и не имеет значение по умолчанию. Значение может быть одним из следующих: Shared, Update, IntentShared, IntentExclusive или Exclusive.

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

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

  • [ @DbPrincipal = ] 'database_principal'
    Пользователь, роль или роль приложения, которые имеют разрешения на объект базы данных. Вызывающий эту функцию участник должен быть членом предопределенной роли базы данных database_principal, dbo или the 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 должна вызываться такое же количество раз для снятия блокировки.

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

USE AdventureWorks2008R2;
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 AdventureWorks2008R2;
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 в базе данных AdventureWorks2008R2.

USE AdventureWorks2008R2;
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 = 'AdventureWorks2008R2', 
     @LockMode = 'Shared';
COMMIT TRAN;
GO