如何在SQLServer中查找长时间未提交的事务?

来源:APP编程网作者:黑豹头衔:草根站长
导读:本期聚焦于小伙伴创作的《如何在SQLServer中查找长时间未提交的事务?》,敬请观看详情。数据库中出现长时间未提交的事务会持续占用锁资源并阻碍日志截断,常引发阻塞与磁盘膨胀。SQLServer通过动态管理视图暴露会话与事务的关联信息,可利用sys.dm_tran_session_transactions配合sys.dm_exec_sessions及sys.dm_tran_active_transactions,按事务开启时间排序筛选出闲置过久的会话。识别后可通过kill命令终止对应连接,或通知业务方补全提交逻辑,避免系统性能劣化。

在SQLServer运行环境中,未提交的事务若长期滞留,会持有锁并占用日志空间,导致其他会话阻塞、tempdb压力上升以及日志文件无法截断。要定位这些事务,核心思路是借助系统动态管理视图(DMV)将“会话”与“事务”关联,并按事务启动时间计算持续时间。

如何在SQLServer中查找长时间未提交的事务?

一、理解SQLServer事务与DMV的关系

SQLServer中的每个事务都会被分配一个事务ID,并在sys.dm_tran_active_transactions中记录其状态、开始时间和类型。而会话(连接)与事务的映射关系保存在sys.dm_tran_session_transactions里,它告诉我们某个session_id当前绑定了哪些transaction_id。最后,sys.dm_exec_sessions提供会话的登录名、主机名、最近请求时间等上下文信息。

单纯查询活动事务视图只能看到事务自身,无法知道是谁开启的;单纯看会话视图又看不到未提交事务的细节。因此必须把三张视图通过transaction_id和session_id做连接,才能完整刻画“哪个连接、在什么时间、开启了什么类型的事务且一直没提交”。这种关联方式是后续所有查找脚本的基础。

二、使用DMV查找长时间未提交事务

下面脚本以“超过60分钟”为例,筛选出仍未提交且持续时间过长的会话事务。你可以按需调整变量@great_than_minutes。

DECLARE @great_than_minutes INT;
SET @great_than_minutes = 60;

SELECT
    s.session_id AS [会话ID],
    s.login_name AS [登录名],
    s.host_name AS [主机名],
    s.program_name AS [程序名],
    t.transaction_id AS [事务ID],
    at.name AS [事务名称],
    at.transaction_begin_time AS [事务开始时间],
    DATEDIFF(MINUTE, at.transaction_begin_time, GETDATE()) AS [持续分钟],
    CASE at.transaction_type
        WHEN 1 THEN '读/写'
        WHEN 2 THEN '只读'
        WHEN 3 THEN '系统'
        ELSE '未知'
    END AS [事务类型],
    CASE at.transaction_state
        WHEN 0 THEN '未初始化'
        WHEN 1 THEN '已初始化未开始'
        WHEN 2 THEN '活动'
        WHEN 3 THEN '已结束'
        WHEN 4 THEN '已提交'
        WHEN 5 THEN '已回滚'
        ELSE '其他'
    END AS [事务状态]
FROM sys.dm_tran_session_transactions t
INNER JOIN sys.dm_exec_sessions s
    ON t.session_id = s.session_id
INNER JOIN sys.dm_tran_active_transactions at
    ON t.transaction_id = at.transaction_id
WHERE at.transaction_begin_time < DATEADD(MINUTE, -@great_than_minutes, GETDATE())
  AND at.transaction_state = 2
ORDER BY at.transaction_begin_time ASC;

该查询返回的每一行都代表一个“活跃且超时”的未提交事务。通过[持续分钟]列可直观判断严重程度;[登录名]与[程序名]则帮助定位责任应用。若发现某事务已持续数小时,基本可判定为代码遗漏commit或异常未回滚。

需要注意的是,sys.dm_tran_active_transactions中的transaction_begin_time在分布式或嵌套事务场景下可能并非绝对的业务开启时刻,但在绝大多数单机OLTP系统中,它足以作为发现长事务的依据。另外,系统内部事务(transaction_type=3)通常无需干预。

三、进一步分析阻塞与锁占用

找到长事务后,往往还需确认它阻塞了谁。可结合sys.dm_exec_requestssys.dm_tran_locks查看其持有锁模式及被阻塞会话。

SELECT
    r.session_id AS [被阻塞会话],
    r.blocking_session_id AS [阻塞源会话],
    r.wait_type AS [等待类型],
    r.wait_time AS [等待毫秒],
    l.resource_type AS [锁资源类型],
    l.request_mode AS [锁模式]
FROM sys.dm_exec_requests r
LEFT JOIN sys.dm_tran_locks l
    ON r.session_id = l.request_session_id
WHERE r.blocking_session_id <> 0
  AND r.blocking_session_id IN (
      SELECT session_id FROM sys.dm_tran_session_transactions
  );

上述脚本列出当前正被长事务会话阻塞的请求,以及它们等待的锁资源类别。如果长事务持有OBJECT或KEY类型的排他锁(X),影响面通常较大。此时应评估是在业务低峰期终止会话,还是推动应用修复。

在生产环境,建议将第一段查找脚本配置为定时作业,超过阈值即报警。这样无需人工巡检,也能在事务拖垮性能前介入。

四、处理长时间未提交事务的方法

确认某会话确实为僵死事务且无法由应用自行提交后,可使用KILL命令结束该会话,SQLServer会对其事务做回滚释放锁与日志。

-- 将 75 替换为实际查到的会话ID
KILL 75;

KILL会引发事务回滚,若事务很大,回滚可能耗时较久,期间系统仍可能有一定压力,但远比任其长期占用要好。更根本的做法是与开发团队核对代码:检查是否使用了隐式事务(SET IMPLICIT_TRANSACTIONS ON)、是否在catch块中遗漏ROLLBACK、或是否在连接池回收前未提交。

此外,开启SET XACT_ABORT ON能让语句错误时自动终止并回滚整个事务,减少“半开不提交”的概率。对关键批处理,还应加上事务超时控制,避免无限等待。

五、预防与监控建议

除了被动查找,建立长效机制更重要。可在监控平台定时采集DMV数据,绘制事务持续时间趋势图;对超过5分钟未提交的事务发黄牌,超过30分钟红牌并通知负责人。

阈值动作
5分钟记录日志并标记观察
30分钟发送告警给DBA与应用负责人
60分钟评估后执行KILL并复盘代码

通过视图查询加流程规范,能显著降低长事务引发故障的概率。本质上,查找只是手段,让事务“短平快”才是目标。

SQLServer未提交事务sys.dm_tran_session_transactions修改时间:2026-08-04 03:30:13

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。