Share via


sp_getapplock (Transact-SQL)

van toepassing op:SQL ServerAzure SQL DatabaseAzure SQL Managed InstanceSQL-database in Microsoft Fabric

Plaatst een slot op een applicatiebron.

Transact-SQL syntaxis-conventies

Syntaxis

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

Arguments

[ @Resource = ] N'Resource'

Een string die een naam specificeert die de lockresource identificeert. @Resource is nvarchar(255), met een standaard van NULL. Als een resource string langer is dan nvarchar(255), wordt de waarde afgekapt tot nvarchar(255).

De applicatie moet ervoor zorgen dat de naam van de bron uniek is. De opgegeven naam wordt intern gehasht in een waarde die kan worden opgeslagen in de SQL Server lock manager.

@Resource is binair vergeleken en dus hoofdlettergevoelig ongeacht de collatie-instellingen van de huidige database.

Opmerking

Nadat een applicatievergrendeling is verkregen, kunnen alleen de eerste 32 tekens in platte tekst worden opgehaald; de rest wordt gehasht.

[ @LockMode = ] 'LockMode'

De vergrendelingsmodus die voor een bepaalde bron moet worden verkregen. @LockMode is varchar(32), zonder standaard, en is een van de volgende waarden:

  • Shared
  • Update
  • IntentShared
  • IntentExclusive
  • Exclusive

Voor meer informatie, zie vergrendelingsmodi.

[ @LockOwner = ] 'LockOwner'

De eigenaar van het slot, wat de @LockOwner waarde is toen het slot werd aangevraagd. @LockOwner is varchar(32), met een standaard van Transaction. De waarde kan ook zijn Session. Wanneer de @LockOwner waarde standaard is Transactionof expliciet is gespecificeerd, sp_getapplock moet deze worden uitgevoerd vanuit een transactie.

[ @LockTimeout = ] LockTime-out

Een lock-time-out waarde in milliseconden. @LockTimeout is int, en de standaardwaarde is dezelfde als de waarde die door @@LOCK_TIMEOUTwordt teruggegeven. Een waarde van -1 (standaard) geeft aan dat er geen time-out periode is (dat wil zeggen, eeuwig wachten). Om aan te geven dat een lock-verzoek een retourcode van -1 moet teruggeven in plaats van te wachten op de lock wanneer het verzoek niet direct kan worden toegekend, specificeer 0.

[ @DbPrincipal = ] N'DbPrincipal'

De gebruiker, rol of applicatierol die rechten geeft op een object in een database. @DbPrincipal is sysname, met als standaard .public De aanroeper van de functie moet lid zijn van database_principal, dbo of de db_owner vaste databaserol om de functie succesvol aan te roepen. De standaard is openbaar.

Codewaarden retourneren

>= 0 (succes), of < 0 (mislukking).

Waarde Resultaat
0 De vergrendeling werd succesvol synchroon toegekend.
1 De vergrendeling werd succesvol toegekend nadat er werd gewacht tot andere incompatibele sloten werden vrijgegeven.
-1 Het verzoek om slot liep uit.
-2 Het verzoek om slot is geannuleerd.
-3 Het slotverzoek werd gekozen als slachtoffer van een deadlock.
-999 Geeft een parametervalidatie of andere oproepfout aan.

Opmerkingen

Sloten die op een resource zijn geplaatst, zijn gekoppeld aan ofwel de huidige transactie of de huidige sessie. Sloten die aan de huidige transactie horen, worden vrijgegeven wanneer de transactie commit of terugrolt. Vergrendelingen die aan de sessie horen, worden vrijgegeven wanneer de sessie wordt uitgelogd. Wanneer de server om welke reden dan ook wordt afgesloten, worden alle vergrendelingen opgeheven.

De lockresource die door sp_getapplock wordt aangemaakt, wordt aangemaakt in de huidige database voor de sessie. Elke slotbron wordt geïdentificeerd door de gecombineerde waarden van:

  • De database-ID van de database met de vergrendelingsbron.
  • De databaseprincipal gespecificeerd in de @DbPrincipal-parameter .
  • De slotnaam die in de @Resource parameter wordt gespecificeerd.

Alleen een lid van de databaseprincipal die in de @DbPrincipal-parameter is gespecificeerd, kan applicatielocks verkrijgen die dat principal specificeren. Leden van de DBO en db_owner rollen worden impliciet beschouwd als leden van alle rollen.

Sloten kunnen expliciet worden losgemaakt met sp_releaseapplock. Wanneer een applicatie meerdere keren aanroept sp_getapplock voor dezelfde lockresource, sp_releaseapplock moet deze even vaak worden aangeroepen om de lock vrij te maken. Wanneer een slot wordt geopend met de eigenaar van het Transaction slot, wordt dat slot vrijgegeven wanneer de transactie wordt doorgegaan of teruggedraaid.

Als sp_getapplock meerdere keren wordt aangeroepen voor dezelfde lock-resource, maar de lock mode die in een van de verzoeken wordt gespecificeerd niet hetzelfde is als de bestaande modus, is het effect op de resource een vereniging van de twee lock-modi. In de meeste gevallen betekent dit dat de lock-modus wordt gepromoveerd naar de sterkere van de lock-modi, de bestaande modus, of de nieuw gevraagde modus. Deze sterkere vergrendelingsmodus wordt ingedrukt totdat de vergrendeling uiteindelijk wordt losgelaten, zelfs als er vóór die tijd slotvrijlatingsoproepen plaatsvinden.

Bijvoorbeeld, in de volgende reeks aanroepen wordt de resource in Exclusive modus gehouden in plaats van in Shared modus.

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

Een deadlock met een applicatielock rolt de transactie die de applicatielock heeft aangevraagd, niet terug. Elke rollback die mogelijk nodig is als gevolg van de returnwaarde moet handmatig worden uitgevoerd. Daarom raden we aan om foutcontrole in de code te integreren, zodat als bepaalde waarden worden teruggegeven (bijvoorbeeld -3), een ROLLBACK TRANSACTION of een alternatieve actie wordt gestart.

Hier is een voorbeeld:

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

SQL Server gebruikt de huidige database-ID om de bron te kwalificeren. Daarom, als sp_getapplock wordt uitgevoerd, zelfs met identieke parameterwaarden op verschillende databases, resulteert het resultaat in afzonderlijke locks op afzonderlijke bronnen.

Gebruik de sys.dm_tran_locks dynamische beheerweergave of de sp_lock systeemopgeslagen procedure om vergrendelingsinformatie te onderzoeken, of gebruik SQL Server Profiler om vergrendelingen te monitoren.

Permissions

Vereist lidmaatschap van de openbare rol.

Voorbeelden

Het volgende voorbeeld plaatst een gedeeld slot, dat gekoppeld is aan de huidige transactie, op de resource Form1 in de AdventureWorks2025 database.

USE AdventureWorks2022;
GO

BEGIN TRANSACTION;

DECLARE @result AS INT;

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

COMMIT TRANSACTION;
GO

Het volgende voorbeeld specificeert dbo als databasehoofd.

BEGIN TRANSACTION;

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

COMMIT TRANSACTION;
GO