sp_getapplock (Transact-SQL)

Gäller för:SQL ServerAzure SQL DatabaseAzure SQL Managed InstanceSQL-databas i Microsoft Fabric

Låser en applikationsresurs.

Transact-SQL syntaxkonventioner

Syntax

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

Arguments

[ @Resource = ] N'Resource'

En sträng som specificerar ett namn som identifierar låsresursen. @Resource är nvarchar(255), med en standard på NULL. Om en resurssträng är längre än nvarchar(255), avkortas värdet till nvarchar(255).

Applikationen måste säkerställa att resursnamnet är unikt. Det angivna namnet hashas internt till ett värde som kan lagras i SQL Server-låshanteraren.

@Resource är binärjämförelset och därmed kasuskänslig oavsett sorteringsinställningarna i den aktuella databasen.

Anmärkning

Efter att ett applikationslås har förvärvats kan endast de första 32 tecknen hämtas i klartext; resten kommer att hashas.

[ @LockMode = ] 'LockMode'

Låsläget som ska erhållas för en viss resurs. @LockMode är varchar(32), utan standard, och är ett av följande värden:

  • Shared
  • Update
  • IntentShared
  • IntentExclusive
  • Exclusive

För mer information, se låslägen.

[ @LockOwner = ] 'Låsägare'

Ägaren till låset, vilket är det @LockOwner värdet när låset begärdes. @LockOwner är varchar(32), med standardvärdet .Transaction Värdet kan också vara Session. När @LockOwner värdet är Transaction, som standard eller explicit specificerat, sp_getapplock måste det utföras inifrån en transaktion.

[ @LockTimeout = ] LockTimeout

Ett låstidsvärde i millisekunder. @LockTimeout är int, och standardvärdet är detsamma som värdet som returneras av @@LOCK_TIMEOUT. Ett värde på -1 (default) indikerar ingen timeout-period (det vill säga vänta för evigt). För att indikera att en låsförfrågan ska returnera en returkod för -1 istället för att vänta på låset när förfrågan inte kan beviljas omedelbart, specificera 0.

[ @DbPrincipal = ] N'DbPrincipal'

Användaren, rollen eller applikationsrollen som ger behörigheter till ett objekt i en databas. @DbPrincipal är sysname, med standardvärdet .public Anroparen av funktionen måste vara medlem i database_principal, dbo eller den db_owner fasta databasrollen för att funktionen ska kunna anropas framgångsrikt. Standarden är offentlig.

Returnera kodvärden

>= 0 (framgång), eller < 0 (misslyckande).

Värde Result
0 Låset tilldelades framgångsrikt synkront.
1 Låset beviljades framgångsrikt efter att ha väntat på att andra inkompatibla lås skulle släppas.
-1 Låsförfrågan gick ut på tiden.
-2 Låsansökan avbröts.
-3 Låsbegäran valdes som dödlåsningsoffer.
-999 Indikerar en parametervalidering eller annat anropsfel.

Anmärkningar

Lås som placeras på en resurs är kopplade antingen till den aktuella transaktionen eller den aktuella sessionen. Lås kopplade till den aktuella transaktionen släpps när transaktionen commis eller rullas tillbaka. Lås kopplade till sessionen släpps när sessionen loggas ut. När servern stängs av av någon anledning släpps alla lås.

Låsresursen som skapas av sp_getapplock skapas i den aktuella databasen för sessionen. Varje låsresurs identifieras av de kombinerade värdena av:

  • Databas-ID:t för databasen som innehåller låsresursen.
  • Databasprincipen specificerad i @DbPrincipal-parametern .
  • Låsnamnet som anges i parametern @Resource .

Endast en medlem i databasprincipen som anges i parametern @DbPrincipal kan få applikationslås som specificerar just den principen. Medlemmar i DBO- och db_owner-roller betraktas implicit som medlemmar i alla roller.

Lås kan explicit släppas med sp_releaseapplock. När en applikation anropar sp_getapplock flera gånger för samma låsresurs sp_releaseapplock måste anropas lika många gånger för att släppa låset. När ett lås öppnas med låsägaren Transaction släpps det låset när transaktionen genomförs eller rullas tillbaka.

Om sp_getapplock anropas flera gånger för samma låsresurs, men låsläget som anges i någon av förfrågningarna inte är detsamma som det befintliga, är effekten på resursen en union av de två låslägena. I de flesta fall innebär detta att låsläget uppgraderas till det starkare av låslägena, det befintliga läget eller det nybegärda läget. Detta starkare låsläge hålls tills låset slutligen släpps, även om låsfrigöringsanrop sker innan dess.

Till exempel, i följande sekvens av anrop, hålls resursen i Exclusive läge istället för i Shared läge.

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

En deadlock med ett applikationslås rullar inte tillbaka transaktionen som begärde applikationslåset. All rollback som kan krävas på grund av returvärdet måste göras manuellt. Vi rekommenderar därför att felkontroll inkluderas i koden, så att om vissa värden returneras (till exempel -3), initieras en ROLLBACK TRANSACTION eller alternativ åtgärd.

Här är ett exempel:

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 använder det aktuella databas-ID:t för att kvalificera resursen. Därför, om sp_getapplock exekveras även med identiska parametervärden på olika databaser, blir resultatet separata låsningar på separata resurser.

Använd den dynamiska sys.dm_tran_locks hanteringsvyn eller systemlagrad sp_lock procedur för att undersöka låsinformation, eller använd SQL Server Profiler för att övervaka lås.

Permissions

Kräver medlemskap i offentlig roll.

Examples

Följande exempel placerar ett delat lås, som är kopplat till den aktuella transaktionen, på resursen Form1 i databasen AdventureWorks2025 .

USE AdventureWorks2022;
GO

BEGIN TRANSACTION;

DECLARE @result AS INT;

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

COMMIT TRANSACTION;
GO

Följande exempel specificerar dbo som databasens huvudsak.

BEGIN TRANSACTION;

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

COMMIT TRANSACTION;
GO