sp_getapplock (Transact-SQL)

Insere um bloqueio em um recurso de aplicativo.

Ícone de vínculo de tópicoConvenções de sintaxe Transact-SQL

Sintaxe

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

Argumentos

  • [ @Resource = ] 'resource_name'
    É uma cadeia de caracteres especificando um nome que identifica o recurso de bloqueio. O aplicativo deve garantir que o nome do recurso seja exclusivo. O nome especificado é internamente colocado em hash para um valor que pode ser armazenado no gerenciador de bloqueio do SQL Server. resource_name é nvarchar(255) sem padrão. Se uma cadeia de caracteres de recurso for maior que nvarchar(255), será truncado para nvarchar(255).

    resource_name é binário comparado, e assim diferencia maiúsculas e minúsculas independente das configurações de agrupamento do banco de dados atual.

    ObservaçãoObservação

    Depois que um bloqueio de aplicativo for adquirido, somente os primeiros 32 caracteres poderão ser recuperados em texto não criptografado, o restante será em modo hash.

  • [ @LockMode = ] 'lock_mode'
    É o modo de bloqueio que será obtido para um recurso específico. lock_mode é nvarchar(32) e não tem nenhum valor padrão. O valor pode ser um dos seguintes: Shared, Update, IntentShared, IntentExclusive ou Exclusive.

  • [ @LockOwner = ] 'lock_owner'
    É o proprietário do bloqueio, que é o valor de lock_owner quando o bloqueio foi solicitado. lock_owner é nvarchar(32). O valor pode ser Transaction (o padrão) ou Session. Quando o valor lock_owner for Transaction, por padrão ou explicitamente especificado, sp_getapplock deve ser executado a partir de uma transação.

  • [ @LockTimeout = ] 'value'
    É um valor de tempo limite de bloqueio em milissegundos. O valor padrão é igual ao valor retornado por @@LOCK_TIMEOUT. Para indicar que uma solicitação de bloqueio deve retornar um erro em vez de esperar pelo bloqueio quando não for possível conceder a solicitação imediatamente, especifique 0.

  • [ @DbPrincipal = ] 'database_principal'
    É o usuário, função ou função de aplicativo que tem permissões para um objeto em um banco de dados. O chamador da função deve ser um membro de database_principal, dbo ou a função de banco de dados fixa db_owner para chamar a função com êxito. O padrão é público.

Valores de código de retorno

>= 0 (êxito) ou < 0 (falha)

Valor

Resultado

0

O bloqueio foi concedido com sucesso de forma síncrona.

1

O bloqueio foi concedido com sucesso após outros bloqueios incompatíveis terem sido liberados.

-1

A solicitação de bloqueio expirou.

-2

A solicitação de bloqueio foi cancelada.

-3

A solicitação de bloqueio foi selecionada como uma vítima de deadlock.

-999

Indica uma validação de parâmetro ou outro erro de chamada.

Comentários

Bloqueios inseridos em um recurso são associados com a transação atual ou a sessão atual. Os bloqueios associados a uma transação atual são liberados quando a transação for confirmada ou revertida. Bloqueios associados com a sessão são liberados quando a sessão é finalizada. Quando o servidor é desligado por algum motivo, todos os bloqueios são liberados.

O recurso de bloqueio criado por sp_getapplock é criado no banco de dados atual para a sessão. Cada recurso de bloqueio é identificado pelos valores combinados de:

  • A ID do banco de dados que contém o recurso de bloqueio.

  • O princípio de banco de dados especificado no parâmetro @ DbPrincipal.

  • O nome do bloqueio especificado no parâmetro @ Recurso.

Somente um membro do banco de dados principal especificado no parâmetro @ DbPrincipal pode adquirir bloqueios de aplicativo que especificam o banco de dados principal. Membros das funções dbo e db_owner são implicitamente considerados membros de todas as outras funções.

Bloqueios podem ser explicitamente liberados com sp_releaseapplock. Quando um aplicativo chama sp_getapplock várias vezes para o mesmo recurso de bloqueio, sp_releaseapplock deve ser chamado o mesmo número de vezes para liberar o bloqueio.

Se sp_getapplock for chamado várias vezes para o mesmo recurso de bloqueio, mas o modo de bloqueio especificado em qualquer solicitação não for igual ao modo existente, o efeito no recurso será uma união dos dois modos de bloqueio. Na maioria dos casos, isto significa que o modo de bloqueio é promovido para o modo de bloqueio mais forte, o modo existente ou o modo solicitado recentemente. Esse modo de bloqueio mais forte é mantido até que bloqueio seja totalmente liberado, mesmo se chamadas de liberação de bloqueio ocorram antes daquele momento. Por exemplo, na seguinte sequência de chamadas, o recurso é mantido em modo Exclusive ao invés de modo 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

Um deadlock com um bloqueio de aplicativo não reverte a transação que solicitou o bloqueio de aplicativo. Qualquer reversão que poderia ser requerida como resultado do valor de retorno deve ser feita manualmente. Consequentemente, recomendamos que a verificação de erros seja incluída no código de forma que se forem retornados certos valores (por exemplo, -3), um ROLLBACK TRANSACTION ou ação alternativa seja iniciada.

Segue um exemplo:

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 usa o ID de banco de dados atual para qualificar o recurso. Logo, se sp_getapplock for executado, mesmo com valores de parâmetro idênticos em bancos de dados diferentes, o resultado criará bloqueios separados em recursos separados.

Use a exibição de gerenciamento dinâmico sys.dm_tran_locks ou o procedimento armazenado de sistema sp_lock para examinar informações de bloqueio ou use SQL Server Profiler para monitorar os bloqueios.

Permissões

Requer associação na função public.

Exemplos

O exemplo a seguir insere um bloqueio compartilhado que é associado à transação atual no recurso Form1 no banco de dados AdventureWorks2008R2.

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

O exemplo a seguir especifica dbo como o principal do banco de dados.

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