最直接线索是关联 sys.dm_exec_sessions 与 sys.dm_tran_active_transactions:通过 session_id 和 transaction_id 连接二者,重点检查 open_transaction_count > 0 且 transaction_begin_time 显著早于当前时间(如超5分钟)、last_request_end_time 久远、status = 'sleeping' 的会话。

查 sys.dm_exec_sessions 和 sys.dm_tran_active_transactions
长事务最直接的线索藏在两个动态管理视图里:sys.dm_exec_sessions 和 sys.dm_tran_active_transactions。前者告诉你谁连着、连了多久、是否在跑语句;后者告诉你事务从什么时候开始、状态如何、有没有被阻塞。关键不是单独看某一个,而是用 transaction_id 把它们 JOIN 起来。
常见错误是只查 sys.dm_tran_active_transactions,却漏掉 session_id,导致无法定位到具体连接——比如某个应用连接池里的空闲连接,其实还挂着未提交的事务。
- 必须关联
sys.dm_exec_sessions.session_id = sys.dm_tran_session_transactions.session_id,再通过transaction_id连到sys.dm_tran_active_transactions - 重点关注
open_transaction_count > 0且last_request_end_time是很久以前(比如 30 分钟前)的会话 -
transaction_begin_time比当前时间早超过 5 分钟,基本可判定为异常长事务
识别事务是否处于“活动但无操作”状态
很多长事务不是卡在 SQL 执行上,而是应用层拿到结果后忘了 COMMIT 或 ROLLBACK。这时候 sys.dm_exec_requests 里往往查不到正在运行的请求(status = 'sleeping'),但事务依然开着。
容易踩的坑是误以为 status = 'sleeping' 就代表安全——其实只要 open_transaction_count > 0,这个 sleeping 会话就可能正锁着表、阻塞别人。
- 检查
sys.dm_exec_sessions.status为'sleeping',同时sys.dm_exec_sessions.open_transaction_count > 0 - 结合
sys.dm_exec_sessions.last_request_end_time判断“睡了多久”,如果远大于业务预期(如订单处理通常 2 秒内完成),就是可疑点 - 用
sys.dm_exec_sql_text(sql_handle)查最后一次执行的语句,常能发现是BEGIN TRAN后没配对的COMMIT
用存储过程封装自动检测逻辑
手动拼 DMV 查询太费事,写成存储过程可以定时跑、加告警、甚至集成进监控脚本。核心是把上面两个判断条件固化下来,避免每次都要重写 JOIN 条件。
注意别硬编码阈值——比如“5 分钟”这种值,应该作为 @MaxOpenMinutes 参数传入,方便不同环境(开发/生产)灵活调整。
- 参数建议至少包含:
@MaxOpenMinutes INT = 5、@ExcludeSystemSessions BIT = 1(过滤掉系统会话如 LAZY WRITER) - 返回字段必须含:
session_id、login_name、host_name、program_name、transaction_begin_time、last_request_end_time - 避免在存储过程中直接
KILL会话——那是运维动作,存储过程只负责“报”,不负责“杀”
为什么不能只依赖 DBCC OPENTRAN?
DBCC OPENTRAN 看起来简单,但它只返回每个数据库里“最早的活跃事务”,信息极其有限:没有 session_id、没有登录名、没有最后执行语句。遇到并发多、事务多的库,它几乎等于没用。
更麻烦的是,它不区分事务是真正在执行,还是只是 open 着等应用提交。线上出问题时,你真正需要的是“哪个应用、哪台机器、哪个用户、干了什么还没收尾”,而不是“最早那个事务是啥时候开的”。
-
DBCC OPENTRAN只适合快速确认“有没有老事务”,不适合定位和分析 - 它不支持 WHERE 过滤、不能 JOIN 其他视图、返回结果无法被 SELECT INTO 或 INSERT INTO
- 在高并发 OLTP 场景下,它的输出经常滞后或不准,尤其当事务刚开启就挂起时

















