sp_getapplock (Transact-SQL)

適用於:SQL ServerAzure SQL DatabaseAzure SQL 受控執行個體

將鎖定放在應用程式資源上。

Transact-SQL 語法慣例

語法

  
sp_getapplock [ @Resource = ] 'resource_name' ,  
     [ @LockMode = ] 'lock_mode'   
     [ , [ @LockOwner = ] 'lock_owner' ]   
     [ , [ @LockTimeout = ] 'value' ]  
     [ , [ @DbPrincipal = ] 'database_principal' ]  
[ ; ]  

引數

[ @Resource= ] 'resource_name'
這是指定識別鎖定資源的名稱的字串。 應用程式必須確保資源名稱是唯一的。 指定的名稱會在內部哈希為可儲存在 SQL Server 鎖定管理員中的值。 resource_name為 nvarchar(255),沒有預設值。 如果資源字串超過 nvarchar(255),則會截斷為 nvarchar(255)。

resource_name是二進位比較,因此不論目前資料庫的定序設定為何,都會區分大小寫。

注意

取得應用程式鎖定之後,只能以純文字擷取前 32 個字元:其餘部分將會進行哈希處理。

[ @LockMode= ] 'lock_mode'
這是要針對特定資源取得的鎖定模式。 lock_mode為 varchar(32),且沒有預設值。 此值可以是下列任一項: SharedUpdateIntentSharedIntentExclusiveExclusive。 如需詳細資訊,請參閱 鎖定模式

[ @LockOwner= ] 'lock_owner'
這是鎖定的擁有者,這是 要求鎖定時lock_owner 值。 lock_owner是 varchar(32)。 此值可以是 Transaction (預設值) 或 Session當lock_owner值為 Transaction 時,根據預設或明確指定,sp_getapplock必須在交易內執行。

[ @LockTimeout= ] 'value'
這是以毫秒為單位的鎖定逾時值。 默認值與@@LOCK_TIMEOUT所傳回的值相同。 -1 值 (預設值) 表示沒有逾時期限 (也就是永久等待)。 若要指出鎖定要求應該傳回 -1 的傳回碼,而不是在無法立即授與要求時等候鎖定,請指定 0。

[ @DbPrincipal= ] 'database_principal'
這是具有資料庫中物件許可權的使用者、角色或應用程式角色。 函式的呼叫端必須是 database_principal、dbo 或db_owner固定資料庫角色的成員,才能成功呼叫函式。 預設值是公用。

傳回碼值

>= 0(成功),或 < 0 (失敗)

結果
0 鎖定已成功以同步方式授與。
1 等候其他不相容的鎖定釋出之後,已成功授與鎖定。
-1 鎖定要求逾時。
-2 鎖定要求已取消。
-3 鎖定要求已選擇為死結受害者。
-999 表示參數驗證或其他呼叫錯誤。

備註

資源上放置的鎖定會與目前交易或目前會話相關聯。 當交易認可或回復時,會釋放與目前交易相關聯的鎖定。 當會話註銷時,會釋放與會話相關聯的鎖定。當伺服器因任何原因關閉時,會釋放所有鎖定。

sp_getapplock所建立的鎖定資源會在會話的目前資料庫中建立。 每個鎖定資源都是透過下列組合值來識別:

  • 包含鎖定資源之資料庫的資料庫識別碼。

  • 參數中指定的 @DbPrincipal 資料庫主體。

  • 參數中指定的 @Resource 鎖定名稱。

只有參數中指定的 @DbPrincipal 資料庫主體成員可以取得指定該主體的應用程序鎖定。 dbo 和db_owner角色的成員會隱含地視為所有角色的成員。

使用 sp_releaseapplock 可以明確釋放鎖定。 當應用程式呼叫相同鎖定資源的多次sp_getapplock時,sp_releaseapplock必須呼叫相同次數才能釋放鎖定。 使用鎖定擁有者開啟 Transaction 鎖定時,交易認可或回復時就會釋放該鎖定。

如果針對相同的鎖定資源呼叫sp_getapplock多次,但在任何要求中指定的鎖定模式與現有模式不同,則對資源的影響是兩種鎖定模式的聯集。 在大部分情況下,這表示鎖定模式會升階為鎖定模式、現有模式或新要求的模式。 這個更強的鎖定模式會保留,直到鎖定最終釋放為止。 例如,在下列一連串的呼叫中,資源會保留在模式中 Exclusive ,而不是在 模式中 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  

具有應用程式鎖定的死結不會回復要求應用程式鎖定的交易。 傳回值可能需要的任何復原都必須手動完成。 因此,建議您在程式代碼中包含錯誤檢查,以便傳回特定值(例如 -3),就會起始 ROLLBACK TRANSACTION 或替代動作。

以下是範例:

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 會使用目前的資料庫標識碼來限定資源。 因此,如果執行sp_getapplock,即使在不同資料庫上使用相同的參數值,結果也會是個別資源的個別鎖定。

使用sys.dm_tran_locks動態管理檢視或sp_lock系統預存程式來檢查鎖定資訊,或使用 SQL Server Profiler 監視鎖定。

權限

需要 public 角色中的成員資格。

範例

下列範例會在資料庫中的資源上Form1AdventureWorks2022放置與目前交易相關聯的共享鎖定。

USE AdventureWorks2022;  
GO  
BEGIN TRAN;  
DECLARE @result int;  
EXEC @result = sp_getapplock @Resource = 'Form1',   
               @LockMode = 'Shared';  
COMMIT TRAN;  
GO  

下列範例會將 dbo 指定為資料庫主體。

BEGIN TRAN;  
EXEC sp_getapplock @DbPrincipal = 'dbo', @Resource = 'AdventureWorks2022',   
     @LockMode = 'Shared';  
COMMIT TRAN;  
GO  

另請參閱

APPLOCK_MODE (Transact-SQL)
APPLOCK_TEST (Transact-SQL)
sp_releaseapplock (Transact-SQL)