sp_getapplock (Transact-SQL)
Область применения: SQL Server База данных SQL Azure Управляемый экземпляр SQL Azure
Размещает блокировку на ресурсе приложения.
Соглашения о синтаксисе Transact-SQL
Синтаксис
sp_getapplock
[ [ @Resource = ] N'Resource' ]
, [ @LockMode = ] 'LockMode'
[ , [ @LockOwner = ] 'LockOwner' ]
[ , [ @LockTimeout = ] LockTimeout ]
[ , [ @DbPrincipal = ] N'DbPrincipal' ]
[ ; ]
Аргументы
[ @Resource = ] N'Ресурс
Строка, указывающая имя, определяющее ресурс блокировки. @Resource — nvarchar(255) с значением по умолчаниюNULL
. Если строка ресурса длиннее nvarchar(255), значение усечено до nvarchar(255).
Приложение должно гарантировать уникальность имени ресурса. Указанное имя хэшируется внутренне в значение, которое может храниться в диспетчере блокировки SQL Server.
@Resource сравнивается с двоичными данными, поэтому учитывается регистр независимо от параметров сортировки текущей базы данных.
Примечание.
После того как произойдет блокировка приложения, только первые 32 символа могут быть получены в виде обычного текста; остаток будет хэширован.
[ @LockMode = ] 'LockMode'
Режим блокировки для определенного ресурса. @LockMode — varchar(32), без значения по умолчанию и является одним из следующих значений:
Shared
Update
IntentShared
IntentExclusive
Exclusive
Дополнительные сведения см. в режимах блокировки.
[ @LockOwner = ] 'LockOwner'
Владелец блокировки, который является значением @LockOwner при запросе блокировки. @LockOwner — varchar(32) с значением по умолчаниюTransaction
. Значение также может быть Session
. Если значение Transaction
@LockOwner по умолчанию или указано явным образом, sp_getapplock
необходимо выполнить из транзакции.
[ @LockTimeout = ] LockTimeout
Значение времени ожидания блокировки в миллисекундах. @LockTimeout имеет значение int, а значение по умолчанию совпадает со значением@@LOCK_TIMEOUT
, возвращаемым . Значение -1
(по умолчанию) означает отсутствие периода ожидания (т. е. ожидание навсегда). Чтобы указать, что запрос на блокировку должен возвращать возвращаемый код -1
вместо ожидания блокировки, когда запрос не может быть предоставлен немедленно, укажите 0
.
[ @DbPrincipal = ] N'DbPrincipal'
Роль пользователя, роли или приложения, которая имеет разрешения на объект в базе данных. @DbPrincipal — sysname с значением по умолчаниюpublic
. Вызывающий объект функции должен быть членом database_principal, dbo или предопределенной ролью базы данных db_owner для успешного вызова функции. Значение по умолчанию является общедоступным.
Значения кода возврата
>= 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 TRANSACTION;
DECLARE @result INT;
EXEC @result = sp_getapplock
@Resource = 'Form1',
@LockMode = 'Shared';
COMMIT TRANSACTION;
GO
В данном примере в качестве участника базы данных задается dbo
.
BEGIN TRANSACTION;
EXEC sp_getapplock
@DbPrincipal = 'dbo',
@Resource = 'AdventureWorks2022',
@LockMode = 'Shared';
COMMIT TRANSACTION;
GO