sp_getapplock (Transact-SQL)
Si applica a: SQL Server Database SQL di Azure Istanza gestita di SQL di Azure
Acquisisce un blocco su una risorsa di applicazione.
Convenzioni relative alla sintassi Transact-SQL
Sintassi
sp_getapplock
[ [ @Resource = ] N'Resource' ]
, [ @LockMode = ] 'LockMode'
[ , [ @LockOwner = ] 'LockOwner' ]
[ , [ @LockTimeout = ] LockTimeout ]
[ , [ @DbPrincipal = ] N'DbPrincipal' ]
[ ; ]
Argomenti
[ @Resource = ] N'Risorsa'
Stringa che specifica un nome che identifica la risorsa di blocco. @Resource è nvarchar(255), con un valore predefinito .NULL
Se una stringa di risorsa è più lunga di nvarchar(255),il valore viene troncato a nvarchar(255).
L'applicazione deve garantire che il nome della risorsa sia univoco. Il nome specificato viene sottoposto internamente all'hashing in un valore che può essere archiviato nella gestione blocchi di SQL Server.
@Resource viene confrontato in modo binario e pertanto fa distinzione tra maiuscole e minuscole indipendentemente dalle impostazioni delle regole di confronto del database corrente.
Nota
Dopo l'acquisizione di un blocco a livello di applicazione, è possibile recuperare solo i primi 32 caratteri in testo normale. La parte rimanente viene sottoposta a hashing.
[ @LockMode = ] 'LockMode'
Modalità di blocco da ottenere per una determinata risorsa. @LockMode è varchar(32), senza impostazione predefinita ed è uno dei valori seguenti:
Shared
Update
IntentShared
IntentExclusive
Exclusive
Per altre informazioni, vedere Modalità di blocco.
[ @LockOwner = ] 'LockOwner'
Proprietario del blocco, ovvero il valore @LockOwner quando è stato richiesto il blocco. @LockOwner è varchar(32), con un valore predefinito .Transaction
Il valore può anche essere Session
. Quando il valore @LockOwner è Transaction
, per impostazione predefinita o specificato in modo esplicito, sp_getapplock
deve essere eseguito dall'interno di una transazione.
[ @LockTimeout = ] LockTimeout
Valore di timeout del blocco in millisecondi. @LockTimeout è int e il valore predefinito è uguale al valore restituito da @@LOCK_TIMEOUT
. Un valore ( -1
impostazione predefinita) indica un periodo di timeout (ovvero attendere per sempre). Per indicare che una richiesta di blocco deve restituire un codice restituito anziché -1
attendere il blocco quando la richiesta non può essere concessa immediatamente, specificare 0
.
[ @DbPrincipal = ] N'DbPrincipal'
Ruolo utente, ruolo o applicazione che è autorizzato a un oggetto in un database. @DbPrincipal è sysname, con un valore predefinito .public
Il chiamante della funzione deve essere membro di database_principal, dbo o del ruolo predefinito del database db_owner per chiamare correttamente la funzione. Il valore predefinito è pubblico.
Valori del codice restituito
>= 0
(esito positivo) o < 0
(errore).
Valore | Risultato |
---|---|
0 |
Il blocco è stato concesso in modo sincrono. |
1 |
Il blocco è stato concesso dopo il rilascio di altri blocchi incompatibili. |
-1 |
La richiesta di blocco è scaduta. |
-2 |
La richiesta di blocco è stata annullata. |
-3 |
La richiesta di blocco è stata scelta come vittima del deadlock. |
-999 |
Indica un errore di convalida di un parametro o un altro errore di chiamata. |
Osservazioni:
I blocchi acquisiti per una risorsa sono associati alla transazione o alla sessione corrente. I blocchi associati alla transazione corrente vengono rilasciati in corrispondenza del commit o del rollback della transazione. I blocchi associati alla sessione vengono rilasciati quando la sessione viene disconnessa. Quando il server viene arrestato per qualsiasi motivo, tutti i blocchi vengono rilasciati.
La risorsa di blocco creata da sp_getapplock
viene creata nel database corrente per la sessione. Ogni risorsa di blocco viene identificata tramite la combinazione dei valori seguenti:
- ID del database contenente la risorsa di blocco.
- Entità di database specificata nel parametro @DbPrincipal .
- Nome di blocco specificato nel parametro @Resource.
Solo un membro dell'entità di database specificata nel parametro @DbPrincipal può acquisire blocchi dell'applicazione che specificano tale entità. I membri dei ruoli dbo e db_owner vengono considerati implicitamente membri di tutti i ruoli.
I blocchi possono essere rilasciati in modo esplicito con sp_releaseapplock
. Quando un'applicazione chiama sp_getapplock
più volte per la stessa risorsa di blocco, sp_releaseapplock
deve essere chiamato lo stesso numero di volte per rilasciare il blocco. Quando un blocco viene aperto con il proprietario del Transaction
blocco, tale blocco viene rilasciato quando viene eseguito il commit o il rollback della transazione.
Se sp_getapplock
viene chiamato più volte per la stessa risorsa di blocco, ma la modalità di blocco specificata in una delle richieste non corrisponde alla modalità esistente, l'effetto sulla risorsa è un'unione delle due modalità di blocco. Nella maggior parte dei casi la modalità di blocco viene promossa in base alla modalità che risulta più restrittiva tra quella esistente e quella nuova. Questa modalità di blocco più forte viene mantenuta fino al rilascio del blocco anche se le chiamate di rilascio del blocco si verificano prima di quel momento.
Nella sequenza di chiamate seguente, ad esempio, la risorsa viene mantenuta in modalità Exclusive
anziché in modalità 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 deadlock con un blocco dell'applicazione non esegue il rollback della transazione che ha richiesto il blocco dell'applicazione. Le eventuali operazioni di rollback richieste a causa del valore restituito devono essere eseguite in modo manuale. Pertanto, è consigliabile includere il controllo degli errori nel codice, in modo che, se vengono restituiti determinati valori (ad esempio , -3
), viene avviata un'azione ROLLBACK TRANSACTION
alternativa o .
Ecco un esempio:
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 l'ID del database corrente per qualificare la risorsa. Pertanto, se sp_getapplock
viene eseguito, anche con valori di parametro identici in database diversi, il risultato è blocchi separati su risorse separate.
Usare la sys.dm_tran_locks
visualizzazione a gestione dinamica o la stored procedure di sp_lock
sistema per esaminare le informazioni di blocco o usare SQL Server Profiler per monitorare i blocchi.
Autorizzazioni
È richiesta l'appartenenza al ruolo public .
Esempi
Nell'esempio seguente viene inserito un blocco condiviso, associato alla transazione corrente, nella risorsa Form1
del database AdventureWorks2022
.
USE AdventureWorks2022;
GO
BEGIN TRANSACTION;
DECLARE @result INT;
EXEC @result = sp_getapplock
@Resource = 'Form1',
@LockMode = 'Shared';
COMMIT TRANSACTION;
GO
Nell'esempio seguente viene specificato dbo
come entità di database.
BEGIN TRANSACTION;
EXEC sp_getapplock
@DbPrincipal = 'dbo',
@Resource = 'AdventureWorks2022',
@LockMode = 'Shared';
COMMIT TRANSACTION;
GO