如何通过查询清除sys.dm_tran_locks中的活动锁?
如何清除SQL Server中的活动锁?
一、先定位持有锁的会话
用以下查询列出当前数据库的所有活动锁(自动排除当前操作会话和普通共享锁):
-- 列出当前数据库的所有锁 SELECT TL.resource_type AS 资源类型 ,TL.resource_description AS 资源描述 ,TL.request_mode AS 请求模式 ,TL.request_type AS 请求类型 ,TL.request_status AS 请求状态 ,TL.request_owner_type AS 请求所有者类型 ,TAT.[name] AS 事务名称 ,TAT.transaction_begin_time AS 事务开始时间 ,DATEDIFF(ss, TAT.transaction_begin_time, GETDATE()) AS 事务持续时长(秒) ,ES.session_id AS 会话ID ,ES.login_name AS 登录名 ,COALESCE(OBJ.name, PAROBJ.name) AS 对象名称 ,PARIDX.name AS 索引名称 ,ES.host_name AS 主机名 ,ES.program_name AS 程序名称 FROM sys.dm_tran_locks AS TL INNER JOIN sys.dm_exec_sessions AS ES ON TL.request_session_id = ES.session_id LEFT JOIN sys.dm_tran_active_transactions AS TAT ON TL.request_owner_id = TAT.transaction_id AND TL.request_owner_type = 'TRANSACTION' LEFT JOIN sys.objects AS OBJ ON TL.resource_associated_entity_id = OBJ.object_id AND TL.resource_type = 'OBJECT' LEFT JOIN sys.partitions AS PAR ON TL.resource_associated_entity_id = PAR.hobt_id AND TL.resource_type IN ('PAGE', 'KEY', 'RID', 'HOBT') LEFT JOIN sys.objects AS PAROBJ ON PAR.object_id = PAROBJ.object_id LEFT JOIN sys.indexes AS PARIDX ON PAR.object_id = PARIDX.object_id AND PAR.index_id = PARIDX.index_id WHERE TL.resource_database_id = DB_ID() AND ES.session_id <> @@Spid -- 排除当前操作的会话 -- 可选过滤规则:排除普通共享锁 AND TL.request_mode <> 'S' ORDER BY TL.resource_type ,TL.request_mode ,TL.request_type ,TL.request_status ,对象名称 ,ES.login_name;
执行后重点查看会话ID列,找到持有目标锁的对应会话ID。
二、清除锁的操作方式
sys.dm_tran_locks是系统动态管理视图,仅用于查看锁状态,无法直接删除其中的记录。要释放锁,必须终止持有该锁的会话,使用KILL命令:
KILL 目标会话ID; -- 将此处替换为你查询到的实际会话ID
关键注意事项
- 执行
KILL命令需要拥有ALTER ANY CONNECTION权限; - 终止会话会触发该会话中未提交事务的回滚,耗时取决于事务的规模,需耐心等待;
- 优先排查锁产生的根源(比如未提交的长事务、阻塞型查询),避免频繁杀会话影响业务稳定性。
内容的提问来源于stack exchange,提问作者Jebathon
相关产品推荐
相关产品推荐

