Partilhar via


sp_getapplock (Transact-SQL)

Aplica-se a: SQL Server Banco de Dados SQL do Azure Instâ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 = ] N'Resource' ]
    , [ @LockMode = ] 'LockMode'
    [ , [ @LockOwner = ] 'LockOwner' ]
    [ , [ @LockTimeout = ] LockTimeout ]
    [ , [ @DbPrincipal = ] N'DbPrincipal' ]
[ ; ]

Argumentos

@Resource [ = ] N'Recurso'

Uma cadeia de caracteres que especifica um nome que identifica o recurso de bloqueio. @Resource é nvarchar(255), com um padrão de NULL. Se uma cadeia de caracteres de recurso for maior que nvarchar(255), o valor será truncado para nvarchar(255).

O aplicativo deve garantir que o nome do recurso seja exclusivo. O nome especificado é hash internamente em um valor que pode ser armazenado no gerenciador de bloqueio do SQL Server.

@Resource é comparada em binário e, portanto, diferencia maiúsculas de minúsculas, independentemente das configurações de ordenação 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 [ = ] 'Modo de bloqueio'

O modo de bloqueio a ser obtido para um recurso específico. @LockMode é varchar(32), sem padrão, e é um dos seguintes valores:

  • Shared
  • Update
  • IntentShared
  • IntentExclusive
  • Exclusive

Para obter mais informações, consulte modos de bloqueio.

@LockOwner [ = ] 'LockOwner'

O proprietário do bloqueio, que é o valor @LockOwner quando o bloqueio foi solicitado. @LockOwner é varchar(32), com um padrão de Transaction. O valor também pode ser Session. Quando o valor @LockOwner é Transaction, por padrão ou especificado explicitamente, sp_getapplock deve ser executado de dentro de uma transação.

@LockTimeout [ = ] Tempo limite de bloqueio

Um valor de tempo limite de bloqueio em milissegundos. @LockTimeout é int e o valor padrão é o mesmo que o valor retornado por @@LOCK_TIMEOUT. Um valor de (padrão) indica que não há período de -1 tempo limite (ou seja, aguarde para sempre). 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 [ = ] N'DbPrincipal'

A função de usuário, função ou aplicativo que é permissões para um objeto em um banco de dados. @DbPrincipal é sysname, com um padrão de public. O chamador da função deve ser membro de database_principal, dbo ou da função de banco de dados fixa db_owner para chamar a função com êxito. O padrão é public.

Valores do código de retorno

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

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. 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 parâmetro @DbPrincipal .
  • O nome do bloqueio especificado no parâmetro @Resource.

Somente um membro da entidade de banco de dados especificada no parâmetro @DbPrincipal pode adquirir bloqueios de aplicativo que especificam essa entidade de segurança. Os membros das funções dbo e db_owner são implicitamente considerados membros de todas as funções.

Os bloqueios podem ser liberados explicitamente 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 Transaction bloqueio, esse bloqueio é liberado 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 uma das solicitações não for o mesmo que o 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, mesmo que as chamadas de liberação de bloqueio ocorram antes desse tempo.

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 do aplicativo. Qualquer reversão que poderia ser requerida como resultado do valor de retorno deve ser feita manualmente. Portanto, recomendamos que a verificação de erros seja incluída no código, para que, se determinados valores forem retornados (por exemplo, -3), uma ROLLBACK TRANSACTION ação alternativa seja iniciada.

Veja 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. Portanto, se sp_getapplock for executado, mesmo com valores de parâmetro idênticos em bancos de dados diferentes, o resultado são bloqueios separados em recursos separados.

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

Permissões

Requer associação à função pública .

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 TRANSACTION;

DECLARE @result INT;

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

COMMIT TRANSACTION;
GO

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

BEGIN TRANSACTION;

EXEC sp_getapplock
    @DbPrincipal = 'dbo',
    @Resource = 'AdventureWorks2022',
    @LockMode = 'Shared';

COMMIT TRANSACTION;
GO