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


sys.sp_getapplock (Transact-SQL)

Применимо к:SQL ServerAzure SQL DatabaseAzure SQL Managed InstanceSQL в базе данных Microsoft Fabric

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

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

Синтаксис

sys.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 — varchar(32) с значением по умолчаниюTransaction. Значение также может быть Session. по умолчанию или указано явным образом, Transaction необходимо выполнить из транзакции.

[ @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 AdventureWorks2025;
GO

BEGIN TRANSACTION;

DECLARE @result AS INT;

EXECUTE
    @result = sp_getapplock
    @Resource = 'Form1',
    @LockMode = 'Shared';

EXECUTE
    @result = sp_getapplock
    @Resource = 'Form1',
    @LockMode = 'Exclusive';

EXECUTE
    @result = sp_releaseapplock
    @Resource = 'Form1';

COMMIT TRANSACTION;
GO

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

Приведем пример:

USE AdventureWorks2025;
GO

BEGIN TRANSACTION;

DECLARE @result AS INT;

EXECUTE
    @result = sp_getapplock
    @Resource = 'Form1',
    @LockMode = 'Exclusive';

IF @result = -3
BEGIN
    ROLLBACK;
END
ELSE
BEGIN
    EXECUTE
        @result = sp_releaseapplock
        @Resource = 'Form1';
    COMMIT TRANSACTION;
END
GO

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

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

Разрешения

Требуется членство в роли общедоступной фиксированной базы данных.

Примеры

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

USE AdventureWorks2025;
GO

BEGIN TRANSACTION;

DECLARE @result AS INT;

EXECUTE
    @result = sp_getapplock
    @Resource = 'Form1',
    @LockMode = 'Shared';

COMMIT TRANSACTION;
GO

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

BEGIN TRANSACTION;

EXECUTE sp_getapplock
    @DbPrincipal = 'dbo',
    @Resource = 'AdventureWorks2025',
    @LockMode = 'Shared';

COMMIT TRANSACTION;
GO