如何获取特定事务中执行的SQL查询语句以定位未释放事务问题
如何获取特定事务中执行的SQL查询语句以定位未释放事务问题
嘿,针对你遇到的未释放事务锁表问题,已经能拿到事务ID和会话ID的话,要获取事务里执行的SQL语句来定位代码,其实可以借助SQL Server的动态管理视图(DMV)来实现,下面给你具体的方法和查询语句:
首先,先确认你已经在用的这段查询长期未释放事务的语句:
SELECT trans.session_id AS [SESSION ID] ,login_name AS [Login NAME] ,trans.transaction_id AS [TRANSACTION ID] ,tas.name AS [TRANSACTION NAME] ,tas.transaction_begin_time AS [TRANSACTION BEGIN TIME] FROM sys.dm_tran_active_transactions tas JOIN sys.dm_tran_session_transactions trans ON (trans.transaction_id = tas.transaction_id)
接下来,你可以通过以下几种方式获取该事务内执行的SQL:
- 查看当前会话正在执行的SQL(事务仍活跃执行时适用)
如果这个会话当前还有正在运行的请求,直接关联sys.dm_exec_requests和SQL文本视图就能拿到当前执行的语句:
SELECT r.session_id, r.transaction_id, s.text AS [当前执行的SQL] FROM sys.dm_exec_requests r CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) s WHERE r.session_id = [你的SESSION ID] -- 替换为你拿到的会话ID
查看会话执行过的历史SQL(事务已执行部分语句但未提交/回滚时适用)
如果事务没有正在运行的请求,但你想追溯这个会话之前执行过的SQL,可以用这两个查询:- 获取会话最近执行的SQL:
SELECT c.session_id, s.text AS [最近执行的SQL] FROM sys.dm_exec_connections c CROSS APPLY sys.dm_exec_sql_text(c.most_recent_sql_handle) s WHERE c.session_id = [你的SESSION ID]- 查看会话所有历史查询记录(按执行时间倒序):
SELECT qs.session_id, s.text AS [历史执行SQL], qs.execution_count, qs.last_execution_time FROM sys.dm_exec_query_stats qs CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) s WHERE qs.session_id = [你的SESSION ID] ORDER BY qs.last_execution_time DESC关联事务信息与SQL,精准定位
你还可以把事务的基础信息和SQL语句整合到一个查询里,直接通过事务ID过滤:
SELECT trans.session_id AS [SESSION ID], login_name AS [Login NAME], trans.transaction_id AS [TRANSACTION ID], tas.name AS [TRANSACTION NAME], tas.transaction_begin_time AS [TRANSACTION BEGIN TIME], ISNULL(s_current.text, s_recent.text) AS [关联的SQL语句] FROM sys.dm_tran_active_transactions tas JOIN sys.dm_tran_session_transactions trans ON trans.transaction_id = tas.transaction_id LEFT JOIN sys.dm_exec_requests r ON r.session_id = trans.session_id OUTER APPLY sys.dm_exec_sql_text(r.sql_handle) s_current LEFT JOIN sys.dm_exec_connections c ON c.session_id = trans.session_id OUTER APPLY sys.dm_exec_sql_text(c.most_recent_sql_handle) s_recent WHERE trans.transaction_id = [你的TRANSACTION ID] -- 替换为你拿到的事务ID
需要注意的是,这些DMV里的SQL缓存信息可能会随着SQL Server的缓存清理而丢失,所以建议在发现未释放事务后尽快执行查询。另外如果应用用了连接池,会话ID可能被复用,要确保查询的是当前对应的活跃会话哦。
备注:内容来源于stack exchange,提问作者Liero
相关产品推荐
相关产品推荐

