sp_getapplock (Transact-SQL)

Aplica-se a:SQL ServerBanco de Dados SQL do AzureInstância Gerenciada de SQL do Azure

Insere um bloqueio em um recurso de aplicativo.

Convenções de sintaxe de 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 é hashed internamente em 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), ela será truncada para nvarchar(255).

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

Observaçã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 a ser obtido para um recurso específico. lock_mode é varchar(32) e não tem valor padrão. O valor pode ser qualquer um dos seguintes: Compartilhado, Atualizar, IntencionalCompartilhado, Exclusivo ou Exclusivo. Para obter mais informações, consulte Modos de bloqueio.

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

@LockTimeout= [ ] 'valor'
É um valor de tempo limite de bloqueio em milissegundos. O valor padrão é o mesmo que o valor retornado por @@LOCK_TIMEOUT. Um valor de -1 (padrão) indica nenhum tempo limite (isto é, esperar indefinidamente). Para indicar que uma solicitação de bloqueio deve retornar um Código de Retorno de -1 em vez de aguardar o bloqueio quando a solicitação não puder ser concedida 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 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 do código de retorno

>= 0 (sucesso) ou < 0 (fracasso)

Valor Result
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. Os bloqueios associados à sessão são liberados quando a sessão é desconectada. Quando o servidor é desligado por qualquer 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.

  • A entidade de banco de dados especificada no @DbPrincipal parâmetro.

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

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. Quando um bloqueio é aberto com o proprietário do bloqueio, esse bloqueio é liberado Transaction quando a transação é confirmada ou revertida.

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 o bloqueio seja finalmente liberado. Por exemplo, na seguinte sequência de chamadas, o recurso é mantido em modo Exclusive ao invés de modo 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  

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.

Este é um exemplo:

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  

O SQL Server usa a ID do 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 o modo de exibição de gerenciamento dinâmico sys.dm_tran_locks ou o procedimento armazenado do sistema sp_lock para examinar informações de bloqueio ou use o SQL Server Profiler para monitorar bloqueios.

Permissões

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

Exemplos

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

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

Confira também

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