什么会导致休眠会话有一个打开的事务?

Beg*_*DBA 3 performance sql-server sql-server-2014 query-performance

对于我们的一个 SQL 服务器,有一个过程会造成阻塞混乱:

大多数情况下,该存储过程在一秒内完成,但不知何故使事务保持打开状态。我从 sp_whoisactive 看到的是 status = sleep 并打开 tran 1 持续大约 5-6 分钟。在这段时间内,出现了起伏的阻塞链。

这个 SP 没有像 BEGIN 和 END TRAN 这样的任何事务。它做了一些基本的 select col,col2,col3.... into #temptables from table1 inner join table 2 ... 然后从 #temptable 中选择

当我们从应用程序检查为什么可能有一个事务保持打开状态时,我正在阅读这些场景以在 SP 本身中使用 XACT ABORT ON。但是当不涉及事务时,XACT ABORT 设置如何在这种情况下提供帮助?

请指教

Dan*_*man 6

可以解释这些症状的情景包括:

  1. 应用程序代码已启动事务但未提交

  2. 应用程序 SET IMPLICIT_TRANSACTIONS ON

  3. 存储过程包括 SET IMPLICIT_TRANSACTIONS ON

此 DMV 查询将有助于故障排除。如果隐式启动,事务名称值将是“implicit_transaction”。其他可能的值包括“user_transaction”、“DTC Transaction”或用户指定的事务名称。“user_transaction”值(没有明确的 proc 事务)表示事务必须在客户端启动并且未提交。“DTC Transaction”的值表示分布式事务,也表示应用程序端的事务管理存在问题。

SELECT
      session_tran.session_id
    , active_tran.name 
FROM sys.dm_tran_session_transactions AS session_tran
INNER JOIN sys.dm_tran_active_transactions AS active_tran ON session_tran.transaction_id = active_tran.transaction_id;
Run Code Online (Sandbox Code Playgroud)

SET XACT_ABORT ON将显式事务包含在存储过程中以确保事务回滚是一种很好的做法,尤其是在客户端超时之后。这可能无济于事,因为您的 proc 没有显式事务,除非 proc 碰巧引发错误并因此回滚错误的事务。