適用於:SQL Server
Azure SQL Database
Azure SQL Managed Instance
Microsoft Fabric 中的 SQL 資料庫
將鎖定放在應用程式資源上。
語法
sp_getapplock
[ [ @Resource = ] N'Resource' ]
, [ @LockMode = ] 'LockMode'
[ , [ @LockOwner = ] 'LockOwner' ]
[ , [ @LockTimeout = ] LockTimeout ]
[ , [ @DbPrincipal = ] N'DbPrincipal' ]
[ ; ]
引數
[ @Resource = ] N'資源'
指定識別鎖定資源之名稱的字串。
@Resource為 nvarchar(255),預設值為 NULL。 如果資源字串超過 nvarchar(255),則會將值截斷為 nvarchar(255)。
應用程式必須確保資源名稱是唯一的。 指定的名稱會在內部哈希為可儲存在 SQL Server 鎖定管理員中的值。
@Resource會進行二進位比較,因此不論目前資料庫的定序設定為何,都會區分大小寫。
注意
取得應用程式鎖定之後,只能以純文字擷取前 32 個字元:其餘部分將會進行哈希處理。
[ @LockMode = ] 「鎖定模式」
要針對特定資源取得的鎖定模式。 @LockMode為 varchar(32),不含預設值,且為下列其中一個值:
SharedUpdateIntentSharedIntentExclusiveExclusive
如需詳細資訊,請參閱 鎖定模式。
[ @LockOwner = ] 「鎖主」
鎖定的擁有者,這是 要求鎖定時@LockOwner 值。
@LockOwner為 varchar(32),預設值為 Transaction。 值也可以是 Session。
當@LockOwner值為 Transaction時,預設或明確指定時,sp_getapplock必須從交易內執行。
[ @LockTimeout = ] 鎖定暫停
鎖定逾時值,以毫秒為單位。
@LockTimeout 為 int回的值相同。 值 -1 (預設值) 表示沒有逾時期間 (也就是永遠等候)。 若要指出鎖定要求應該傳回 的 -1 傳回碼,而不是在無法立即授與要求時等候鎖定,請指定 0。
[ @DbPrincipal = ] N'Db校長'
具有資料庫中物件許可權的使用者、角色或應用程式角色。 @DbPrincipal為 sysname。 函式的呼叫端必須是database_principal、dbo 或db_owner固定資料庫角色的成員,才能成功呼叫函式。 預設值為 public。
傳回碼值
>= 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 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
具有應用程式鎖定的死結不會回復要求應用程式鎖定的交易。 傳回值可能需要的任何復原都必須手動完成。 因此,我們建議您在程式代碼中包含錯誤檢查,因此,如果傳回特定值(例如 -3), ROLLBACK TRANSACTION 則會起始 或替代動作。
以下是範例:
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 會使用目前的資料庫標識碼來限定資源。 因此,如果 sp_getapplock 執行 ,即使在不同的資料庫上使用相同的參數值,結果也會是個別資源的個別鎖定。
sys.dm_tran_locks使用動態管理檢視或sp_lock系統預存程式來檢查鎖定資訊,或使用 SQL Server Profiler 監視鎖定。
權限
需要 public 角色的成員資格。
範例
下列範例會在資料庫中的資源上Form1AdventureWorks2025放置與目前交易相關聯的共享鎖定。
USE AdventureWorks2022;
GO
BEGIN TRANSACTION;
DECLARE @result AS INT;
EXECUTE
@result = sp_getapplock
@Resource = 'Form1',
@LockMode = 'Shared';
COMMIT TRANSACTION;
GO
下列範例會將 dbo 指定為資料庫主體。
BEGIN TRANSACTION;
EXECUTE sp_getapplock
@DbPrincipal = 'dbo',
@Resource = 'AdventureWorks2022',
@LockMode = 'Shared';
COMMIT TRANSACTION;
GO