sp_getapplock (Transact-SQL)

Se aplica a:SQL ServerAzure SQL DatabaseAzure SQL Managed Instance

Coloca un bloqueo en un recurso de la aplicación.

Convenciones de sintaxis de Transact-SQL

Sintaxis

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

Argumentos

[ @Resource= ] 'resource_name'
Cadena que indica un nombre que identifica al recurso de bloqueo. La aplicación debe asegurar que el nombre del recurso sea exclusivo. El nombre especificado se aplica un algoritmo hash internamente a un valor que se puede almacenar en el administrador de bloqueos de SQL Server. resource_name es nvarchar(255) sin ningún valor predeterminado. Si una cadena de recurso es mayor que nvarchar(255), se truncará en nvarchar(255).

resource_name se compara binariamente y, por tanto, distingue mayúsculas de minúsculas independientemente de la configuración de intercalación de la base de datos actual.

Nota:

Una vez que se ha adquirido un bloqueo de aplicación, solo los primeros 32 caracteres pueden recuperarse como texto simple; al resto se le aplicará el algoritmo hash.

[ @LockMode= ] 'lock_mode'
Es el modo de bloqueo que se va a obtener para un recurso determinado. lock_mode es varchar(32) y no tiene ningún valor predeterminado. El valor puede ser cualquiera de los siguientes: Shared, Update, IntentShared, IntentExclusive o Exclusive. Para obtener más información, consulte modos de bloqueo.

[ @LockOwner= ] 'lock_owner'
Es el propietario del bloqueo, que es el valor de lock_owner cuando se solicitó el bloqueo. lock_owner es varchar(32). El valor puede ser Transaction (predeterminado) o Session. Cuando el valor de lock_owner es Transaction, de forma predeterminada o se especifica explícitamente, sp_getapplock debe ejecutarse desde dentro de una transacción.

[ @LockTimeout= ] 'value'
Es un valor de tiempo de espera de los bloqueos, en milisegundos. El valor predeterminado es el mismo que el valor devuelto por @@LOCK_TIMEOUT. El valor -1 (predeterminado) indica que no hay límite de espera (es decir que se espera indefinidamente). Para indicar que una solicitud de bloqueo debe devolver un código de retorno de -1 en lugar de esperar al bloqueo cuando no se pueda conceder inmediatamente la solicitud, especifique 0.

[ @DbPrincipal= ] 'database_principal'
Es el usuario, el rol o el rol de aplicación que tiene permisos para un objeto de una base de datos. El autor de la llamada de la función debe ser miembro de database_principal, dbo o el rol fijo de base de datos db_owner para llamar a la función correctamente. El valor predeterminado es public.

Valores de código de retorno

>= 0 (correcto) o < 0 (error)

Value Resultado
0 Se concedió el bloqueo de forma sincrónica.
1 Se concedió el bloqueo después de esperar a que se liberaran otros bloqueos no compatibles.
-1 Se agotó el tiempo de espera de la solicitud de bloqueo.
-2 Se canceló la solicitud de bloqueo.
-3 La solicitud de bloqueo fue objeto del propio bloqueo.
-999 Indica un error de llamada o de validación de parámetros.

Comentarios

Los bloqueos colocados en un recurso se asocian a la transacción o a la sesión actuales. Los bloqueos asociados con la transacción actual se liberan cuando ésta se confirma o se revierte. Los bloqueos asociados a la sesión se liberan cuando se cierra la sesión. Cuando el servidor se cierra por cualquier motivo, se liberan todos los bloqueos.

El bloqueo de recurso creado por sp_getapplock se crea en la base de datos actual para la sesión. Cada recurso de bloqueo se identifica mediante la combinación de los siguientes valores:

  • El Id. de la base de datos que contiene el recurso de bloqueo.

  • Entidad de seguridad de base de datos especificada en el @DbPrincipal parámetro .

  • El nombre del bloqueo indicado en el parámetro @Resource.

Solo un miembro de la entidad de seguridad de base de datos indicado en el parámetro @DbPrincipal puede adquirir bloqueos de aplicación que especifiquen dicha entidad de seguridad. Los miembros de los roles dbo y db_owner se consideran, de manera implícita, miembros de todos los roles.

Es posible liberar los bloqueos de forma explícita con sp_releaseapplock. Si una aplicación llama a sp_getapplock varias veces para el mismo recurso de bloqueo, es necesario llamar a sp_releaseapplock el mismo número de veces para liberar el bloqueo. Cuando se abre un bloqueo con el propietario del Transaction bloqueo, ese bloqueo se libera cuando la transacción se confirma o se revierte.

Si se llama al parámetro sp_getapplock varias veces para el mismo recurso de bloqueo, pero el modo de bloqueo especificado en cualquiera de las solicitudes es diferente del modo existente, el efecto sobre el recurso es la unión de los dos modos de bloqueo. En la mayoría de los casos, esto significa que el modo de bloqueo se promociona al más fuerte de los modos: el modo existente o el recién solicitado. Este modo de bloqueo más fuerte se mantiene hasta que el bloqueo se libera en última instancia. Por ejemplo, en la siguiente secuencia de llamadas, el recurso se mantiene en modo Exclusive, en lugar de 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  

Un interbloqueo con un bloqueo de aplicación no revierte la transacción que solicitó el bloqueo de aplicación. Cualquier reversión que pueda solicitarse como resultado del valor devuelto debe realizarse manualmente. Por tanto, se recomienda incluir la comprobación de errores en el código de forma que si se devuelven determinados valores (por ejemplo, -3), se inicie una acción ROLLBACK TRANSACTION u otra alternativa.

Este es un ejemplo:

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  

SQL Server usa el identificador de base de datos actual para calificar el recurso. Por lo tanto, si se ejecuta sp_getapplock, incluso con los mismos valores de parámetros en bases de datos diferentes, el resultado es bloqueos separados en recursos separados.

Use la vista de administración dinámica sys.dm_tran_locks o el procedimiento almacenado del sistema de sp_lock para examinar la información de bloqueo o use SQL Server Profiler para supervisar bloqueos.

Permisos

Debe pertenecer al rol public.

Ejemplos

En el ejemplo siguiente se coloca un bloqueo compartido, asociado a la transacción actual, en el recurso Form1 de la base de datos AdventureWorks2022.

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

En el siguiente ejemplo se especifica dbo como la entidad de seguridad de base de datos.

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

Consulte también

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