sp_getapplock (Transact-SQL)
Se aplica a: SQL Server Azure SQL Database Azure SQL Managed Instance
Coloca un bloqueo en un recurso de la aplicación.
Convenciones de sintaxis de Transact-SQL
Sintaxis
sp_getapplock
[ [ @Resource = ] N'Resource' ]
, [ @LockMode = ] 'LockMode'
[ , [ @LockOwner = ] 'LockOwner' ]
[ , [ @LockTimeout = ] LockTimeout ]
[ , [ @DbPrincipal = ] N'DbPrincipal' ]
[ ; ]
Argumentos
[ @Resource = ] N'Recurso'
Cadena que especifica un nombre que identifica el recurso de bloqueo. @Resource es nvarchar(255), con un valor predeterminado de NULL
. Si una cadena de recurso es mayor que nvarchar(255) , el valor se trunca en nvarchar(255).
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 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 = ] 'LockMode'
Modo de bloqueo que se va a obtener para un recurso determinado. @LockMode es varchar(32), sin valor predeterminado y es uno de los siguientes valores:
Shared
Update
IntentShared
IntentExclusive
Exclusive
Para obtener más información, consulte modos de bloqueo.
[ @LockOwner = ] 'LockOwner'
Propietario del bloqueo, que es el @LockOwner valor cuando se solicitó el bloqueo. @LockOwner es varchar(32), con un valor predeterminado de Transaction
. El valor también puede ser Session
. Cuando el valor de @LockOwner es Transaction
, de forma predeterminada o se especifica explícitamente, sp_getapplock
debe ejecutarse desde dentro de una transacción.
[ @LockTimeout = ] LockTimeout
Valor de tiempo de espera de bloqueo en milisegundos. @LockTimeout es int y el valor predeterminado es el mismo que el valor devuelto por @@LOCK_TIMEOUT
. Un valor de (valor predeterminado) indica ningún período de tiempo de -1
espera (es decir, esperar para siempre). Para indicar que una solicitud de bloqueo debe devolver un código de retorno de -1
en lugar de esperar al bloqueo cuando la solicitud no se pueda conceder inmediatamente, especifique 0
.
[ @DbPrincipal = ] N'DbPrincipal'
El usuario, el rol o el rol de aplicación que es permisos para un objeto de una base de datos. @DbPrincipal es sysname, con un valor predeterminado de public
. 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 público.
Valores de código de retorno
>= 0
(correcto) o < 0
(error).
Valor | 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 recurso de bloqueo creado por sp_getapplock
se crea en la base de datos actual de 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 parámetro @DbPrincipal .
- El nombre del bloqueo indicado en el parámetro @Resource.
Solo un miembro de la entidad de seguridad de base de datos especificada en el parámetro @DbPrincipal puede adquirir bloqueos de aplicación que especifiquen esa entidad de seguridad. Los miembros de los roles dbo y db_owner se consideran implícitamente miembros de todos los roles.
Los bloqueos se pueden liberar explícitamente con sp_releaseapplock
. Cuando una aplicación llama sp_getapplock
varias veces para el mismo recurso de bloqueo, sp_releaseapplock
se debe llamar al 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 sp_getapplock
se llama varias veces para el mismo recurso de bloqueo, pero el modo de bloqueo especificado en cualquiera de las solicitudes no es el mismo que el modo existente, el efecto en el recurso es una 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 seguro se mantiene hasta que el bloqueo se libera en última instancia incluso si las llamadas de liberación de bloqueo se producen antes de ese tiempo.
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 lo tanto, se recomienda incluir la comprobación de errores en el código, de modo que si se devuelven determinados valores (por ejemplo, -3
), se inicia una ROLLBACK TRANSACTION
acción alternativa o .
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 sp_getapplock
se ejecuta, incluso con valores de parámetro idénticos en bases de datos diferentes, el resultado es bloqueos independientes en recursos independientes.
Use la sys.dm_tran_locks
vista de administración dinámica o el procedimiento almacenado del sp_lock
sistema para examinar la información de bloqueo o use SQL Server Profiler para supervisar los 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 TRANSACTION;
DECLARE @result INT;
EXEC @result = sp_getapplock
@Resource = 'Form1',
@LockMode = 'Shared';
COMMIT TRANSACTION;
GO
En el siguiente ejemplo se especifica dbo
como la entidad de seguridad de base de datos.
BEGIN TRANSACTION;
EXEC sp_getapplock
@DbPrincipal = 'dbo',
@Resource = 'AdventureWorks2022',
@LockMode = 'Shared';
COMMIT TRANSACTION;
GO