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