Condividi tramite


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