sp_getapplock (Transact-SQL)
適用於:SQL Server Azure SQL 資料庫 Azure 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'
要針對特定資源取得的鎖定模式。 @LockMode為 varchar(32),不含預設值,且為下列其中一個值:
Shared
Update
IntentShared
IntentExclusive
Exclusive
如需詳細資訊,請參閱 鎖定模式。
[ @LockOwner = ] 'LockOwner'
鎖定的擁有者,這是 要求鎖定時@LockOwner 值。 @LockOwner為 varchar(32),預設值為 Transaction
。 值也可以是 Session
。 當@LockOwner值為 Transaction
時,預設或明確指定時,sp_getapplock
必須從交易內執行。
[ @LockTimeout = ] LockTimeout
鎖定逾時值,以毫秒為單位。 @LockTimeout 為 int,且預設值與 所@@LOCK_TIMEOUT
傳回的值相同。 值 -1
(預設值) 表示沒有逾時期間 (也就是永遠等候)。 若要指出鎖定要求應該傳回 的 -1
傳回碼,而不是在無法立即授與要求時等候鎖定,請指定 0
。
[ @DbPrincipal = ] N'DbPrincipal'
具有資料庫中物件許可權的使用者、角色或應用程式角色。 @DbPrincipal為 sysname,預設值為 public
。 函式的呼叫端必須是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 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 TRANSACTION;
DECLARE @result INT;
EXEC @result = sp_getapplock
@Resource = 'Form1',
@LockMode = 'Shared';
COMMIT TRANSACTION;
GO
下列範例會將 dbo
指定為資料庫主體。
BEGIN TRANSACTION;
EXEC sp_getapplock
@DbPrincipal = 'dbo',
@Resource = 'AdventureWorks2022',
@LockMode = 'Shared';
COMMIT TRANSACTION;
GO