锁定应用程序资源。
sp_getapplock [ @Resource = ] 'resource_name',
[ @LockMode = ] 'lock_mode'
[ , [ @LockOwner = ] 'lock_owner' ]
[ , [ @LockTimeout = ] 'value' ]
[@Resource =] 'resource_name'
由客户端应用程序指定的锁资源名称。应用程序必须确保资源的唯一性。指定名称经过内部哈希计算后成为可以存储在 SQL Server 锁管理器中的值,resource name 的数据类型为 nvarchar(255),没有默认值。
[@LockMode =] 'lock_mode'
锁模式。lock_mode 的数据类型为 nvarchar(32),没有默认值,它可以为下列值之一:Shared、Update、Exclusive、IntentExclusive、IntentShared。
[@LockOwner =] 'lock_owner'
是锁的所有者。lock_owner 的数据类型为 nvarchar(32),并且可以是 Transaction(默认值)或 Session。当 lock_owner 值为默认值或当显式地指定 Transaction 时,则必须从事务内执行 sp_getapplock。
[@LockTimeout =] 'value'
锁超时值,以毫秒为单位。默认值与 @@LOCK_TIMEOUT 返回的值相同。若要指定对于不能立即授予的锁请求应返回一个错误,而不应等待锁,请指定 0。
>= 0(成功)或 <= 0(失败)
Value | 结果 |
---|---|
0 | 锁已同时成功授予。 |
1 | 在等待释放其它不兼容锁后成功授予锁。 |
-1 | 锁请求超时。 |
-2 | 锁请求被取消。 |
-3 | 选择锁请求作为死锁牺牲品。 |
-999 | 参数验证或其它调用错误。 |
在资源上设置的锁与当前事务或当前会话相关联。当事务提交或回滚时,将释放与当前事务相关联的锁。当会话注销时,将释放与会话相关联的锁。服务器因任何原因而关闭时,都将释放锁。
可以使用 sp_releaseapplock 显式释放锁。如果应用程序为同一锁资源多次调用 sp_getapplock,则必须调用同样次数的 sp_releaseapplock 来释放锁。
如果为同一锁资源多次调用 sp_getapplock,但是指定了不同的锁模式,则对资源的影响将是两个锁模式的联合。多数情况下,这意味着将锁模式提升为现有模式和新请求模式中更强的模式。即使出现锁释放调用,也会把持这一更强的模式直到最终释放锁。例如,在以下调用顺序中,将以排它模式而非共享模式控制资源。
USE Northwind
GO
BEGIN TRAN
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 TRAN
如果应用程序锁发生死锁,则该死锁不会回滚请求此应用程序锁的事务。必须手工完成任何可能导致返回值的潜在请求的回滚。因此,建议在代码中使用错误检查,如果返回某些值(例如 -3),则启动 ROLLBACK TRANSACTION 或选择性操作。
以下是示例:USE Northwind
GO
BEGIN TRAN
DECLARE @result int
EXEC @result = sp_getapplock @Resource = 'Form1',
@LockMode = 'Exclusive'IF @result = '-3'
BEGIN
ROLLBACK TRAN
END
ELSE
BEGIN
EXEC @result = sp_releaseapplock @Resource = 'Form1'
COMMIT TRAN
END
SQL Server 使用当前数据库 ID 来限定资源。因此,如果在不同数据库上执行 sp_getapplock,即便使用了相同的参数值,结果仍然是在单独资源上使用单独锁。
使用 sp_lock 检查锁信息或使用 SQL 事件探查器监视锁。
执行权限默认授予 public 角色。
下面的示例在 Northwind 数据库中的资源"Form1"上设置共享锁,使其与当前事务关联。
USE
Northwind
GO
BEGIN TRAN
DECLARE @result int
EXEC @result = sp_getapplock @Resource = 'Form1',
@LockMode = 'Shared'
COMMIT TRAN
相关文章