Partilhar via


sp_getapplock (Transact-SQL)

Aplica-se a:SQL ServerAzure SQL DatabaseAzure SQL Managed InstanceBase de dados SQL no Microsoft Fabric

Coloca um bloqueio num recurso de aplicação.

Transact-SQL convenções de sintaxe

Sintaxe

sp_getapplock
    [ [ @Resource = ] N'Resource' ]
    , [ @LockMode = ] 'LockMode'
    [ , [ @LockOwner = ] 'LockOwner' ]
    [ , [ @LockTimeout = ] LockTimeout ]
    [ , [ @DbPrincipal = ] N'DbPrincipal' ]
[ ; ]

Arguments

[ @Resource = ] N'Resource'

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

A aplicação deve garantir que o nome do recurso é único. O nome especificado é hashado internamente num valor que pode ser armazenado no gestor de bloqueios do SQL Server.

@Resource é binária comparada e, por isso, é sensível a maiúsculas de minúsculas independentemente das definições de colação da base de dados atual.

Observação

Depois de adquirido um bloqueio de aplicação, apenas os primeiros 32 caracteres podem ser recuperados em texto simples; o restante será analisado.

[ @LockMode = ] 'LockMode'

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

  • Shared
  • Update
  • IntentShared
  • IntentExclusive
  • Exclusive

Para mais informações, veja modos de bloqueio.

[ @LockOwner = ] 'DonoFechaduras'

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

[ @LockTimeout = ] LockTimeout

Um valor de tempo limite de bloqueio em milissegundos. @LockTimeout é int, e o valor padrão é o mesmo que o valor devolvido por @@LOCK_TIMEOUT. Um valor de -1 (por defeito) indica que não há período de time-out (ou seja, espera para sempre). Para indicar que um pedido de bloqueio deve devolver um código de retorno de -1 em vez de esperar pelo bloqueio quando o pedido não pode ser concedido imediatamente, especifique 0.

[ @DbPrincipal = ] N'DbDiretor'

O papel de utilizador, papel ou aplicação que são permissões para um objeto numa base de dados. @DbPrincipal é sysname, com o padrão de public. O chamador da função deve ser membro de database_principal, dbo ou do papel de base de dados fixo db_owner para chamar a função com sucesso. O padrão é público.

Valores de código de retorno

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

Valor Result
0 O bloqueio foi concedido com sucesso de forma síncrona.
1 O cadeado foi concedido com sucesso após esperar que outros cadeados incompatíveis fossem libertados.
-1 O pedido de fechadura expirou.
-2 O pedido de fechadura foi cancelado.
-3 O pedido de bloqueio foi escolhido como vítima de impasse.
-999 Indica uma validação de parâmetros ou outro erro de chamada.

Observações

Bloqueios colocados num recurso estão associados à transação atual ou à sessão atual. Os bloqueios associados à transação atual são libertados quando a transação faz commit ou reverte. Os bloqueios associados à sessão são libertados quando a sessão é encerrada. Quando o servidor desliga por qualquer motivo, todos os bloqueios são libertados.

O recurso de bloqueio criado por sp_getapplock é criado na base de dados atual da sessão. Cada recurso de bloqueio é identificado pelos valores combinados de:

  • O ID da base de dados da base de dados que contém o recurso de bloqueio.
  • O principal da base de dados especificado no parâmetro @DbPrincipal .
  • O nome da fechadura especificado no @Resource parâmetro.

Apenas um membro do principal da base de dados especificado no parâmetro @DbPrincipal pode adquirir bloqueios de aplicação que especifiquem esse principal. Os membros dos papéis dbo e db_owner são implicitamente considerados membros de todos os papéis.

As fechaduras podem ser explicitamente libertadas com sp_releaseapplock. Quando uma aplicação chama sp_getapplock várias vezes para o mesmo recurso de bloqueio, sp_releaseapplock deve ser chamada o mesmo número de vezes para libertar o bloqueio. Quando uma fechadura é aberta com o proprietário Transaction da fechadura, essa fechadura é libertada quando a transação é comprometida ou revertida.

Se sp_getapplock for chamado várias vezes para o mesmo recurso de bloqueio, mas o modo de bloqueio especificado em qualquer um dos pedidos não for o mesmo que o modo existente, o efeito sobre o recurso é a 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 recém-solicitado. Este modo de bloqueio mais forte mantém-se até que o bloqueio seja finalmente libertado, mesmo que as chamadas de libertação do bloqueio ocorram antes desse momento.

Por exemplo, na sequência seguinte de chamadas, o recurso é mantido em Exclusive modo em vez de em Shared modo.

USE AdventureWorks2022;
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

Um deadlock com bloqueio de aplicação não reverte a transação que pediu o bloqueio de aplicação. Qualquer rollback que possa ser necessário devido ao valor de retorno deve ser feito manualmente. Por isso, recomendamos que a verificação de erros seja incluída no código, para que, se certos valores forem devolvidos (por exemplo, -3), seja iniciada uma ROLLBACK TRANSACTION ação alternativa ou alternativa.

Aqui está um exemplo:

USE AdventureWorks2022;
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

O SQL Server utiliza o ID atual da base de dados para qualificar o recurso. Portanto, se sp_getapplock for executado, mesmo com valores de parâmetros idênticos em bases de dados diferentes, o resultado são bloqueios separados em recursos distintos.

Use a sys.dm_tran_locks vista de gestão dinâmica ou o sp_lock procedimento armazenado do sistema para examinar informações de bloqueios, ou utilize o SQL Server Profiler para monitorizar fechaduras.

Permissions

Requer adesão à função pública de .

Examples

O exemplo seguinte coloca um bloqueio partilhado, que está associado à transação atual, no recurso Form1 da AdventureWorks2025 base de dados.

USE AdventureWorks2022;
GO

BEGIN TRANSACTION;

DECLARE @result AS INT;

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

COMMIT TRANSACTION;
GO

O exemplo seguinte especifica dbo como principal da base de dados.

BEGIN TRANSACTION;

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

COMMIT TRANSACTION;
GO