sp_getapplock (Transact-SQL)
適用於:SQL ServerAzure SQL DatabaseAzure 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),且沒有預設值。 此值可以是下列任一項: Shared、 Update、 IntentShared、 IntentExclusive 或 Exclusive。 如需詳細資訊,請參閱 鎖定模式。
[ @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 角色中的成員資格。
範例
下列範例會在資料庫中的資源上Form1
AdventureWorks2022
放置與目前交易相關聯的共享鎖定。
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)
意見反應
https://aka.ms/ContentUserFeedback。
即將登場:在 2024 年,我們將逐步淘汰 GitHub 問題作為內容的意見反應機制,並將它取代為新的意見反應系統。 如需詳細資訊,請參閱:提交並檢視相關的意見反應