You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQL Server分布式锁查询:如何判断指定名称的分布式锁是否存在

SQL Server分布式锁存在性查询方案

原有方案合理性说明

你总结的判断逻辑仅在排他锁测试场景下可得到正确结果,但存在明显局限性:

  • APPLOCK_MODE仅能返回当前会话持有的目标锁模式,其他会话持有的锁无法通过该函数感知,当其他会话持有共享锁等非排他锁时,你的判断逻辑会出现误判
  • 逻辑耦合当前会话状态,无法独立查询任意会话持有的分布式锁

不受当前连接限制的通用查询方案

方案1:查询系统动态视图(无副作用,优先推荐)

通过全局动态视图sys.dm_tran_locks可直接查询所有会话持有的应用锁,无需修改锁状态:

DECLARE @TargetLockName SYSNAME = 'testlock' -- 替换为你要查询的锁名称
DECLARE @TargetDB SYSNAME = DB_NAME() -- 锁所属数据库,默认取当前数据库可手动修改

SELECT 
    CASE WHEN COUNT(1) > 0 THEN 1 ELSE 0 END AS is_lock_exist
FROM sys.dm_tran_locks
WHERE 
    resource_type = 'APPLICATION' -- 应用程序锁标识
    AND DB_NAME(resource_database_id) = @TargetDB
    AND RESOURCE_NAME = CONVERT(VARCHAR(64), HASHBYTES('SHA2_256', @TargetLockName), 2)

注意:该方案需要查询账号拥有VIEW SERVER STATE权限。

方案2:零超时尝试加锁(无权限要求)

如果没有系统视图查询权限,可以通过设置0超时尝试加锁的方式判断,不会造成会话堵塞:

DECLARE @LockResult INT
DECLARE @TargetLockName SYSNAME = 'testlock'

-- 尝试获取排他锁,超时时间设为0,不等待
EXEC @LockResult = sp_getapplock
    @Resource = @TargetLockName,
    @LockMode = 'Exclusive',
    @LockOwner = 'Session',
    @LockTimeout = 0,
    @DbPrincipal = 'public'

IF @LockResult >= 0
BEGIN
    -- 成功获取锁,说明无其他会话持有,立即释放避免占用
    EXEC sp_releaseapplock 
        @Resource = @TargetLockName,
        @LockOwner = 'Session',
        @DbPrincipal = 'public'
    SELECT 0 AS is_lock_exist
END
ELSE
BEGIN
    -- 获取失败,锁已被其他会话持有
    SELECT 1 AS is_lock_exist
END

若需要判断是否存在任意模式的锁,可将@LockMode调整为对应的锁模式参数即可。

内容的提问来源于stack exchange,提问作者Seabizkit

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 21:06:03