-- 3.1.3 通过会话查询事务信息 ( P104 ) -- 这个技巧演示了如何找出更多活动事务的信息。为了进行演示,将描述一个常见的场景:你的应用程序会遇到很多高持时间的阻塞。 -- 你被告知这个应用程序经常在每个查询之前打开显式的事务。-- 为了说明这个场景,将执行如下的SQL(表示应用程序代码引发了并发性问题):SET TRANSACTION ISOLATION LEVEL SERIALIZABLEBEGIN TRANSELECT * FROM HumanResources.DepartmentINSERT HumanResources.Department (Name, GroupName) VALUES('Test','OA')-- 在另一个/新的SQL Server Management Studio 查询窗口,通过查询sys.dm_tran_session_transactions动态管理视图(DMV)来识别所打开的事务:SELECT session_id, transaction_id, is_user_transaction, is_local FROM sys.dm_tran_session_transactions WHERE is_user_transaction = 1-- 这个查询返回如下内容(你实际的会话ID和事务ID会有所不同): ----------------------------------------------------------------------------------------- session_id transaction_id is_user_transaction is_local 54 47941 1 1 ------------------------------------------------------------------------------------------- 现在有会话ID可以使用了,可以通过查询 sys.dm_exec_connections 和 sys.dm_exec_sql_text 来挖掘最近执行的查询的详细信息:SELECT s.text FROM sys.dm_exec_connections c CROSS APPLY sys.dm_exec_sql_text(c.most_recent_sql_handle) s WHERE session_id = 54----------------------------------------------------------------------------------------- text SET TRANSACTION ISOLATION LEVEL SERIALIZABLE BEGIN TRAN SELECT * FROM HumanResources.Department INSERT HumanResources.Department (Name, GroupName) VALUES('Test','OA') ------------------------------------------------------------------------------------------- 因为也从对sys.dm_tran_session_transactions 的第一个查询中得到了事务的ID,所以可以使用sys.dm_tran_active_transactions 来了解更多事务本身的内容:SEELCT transaction_begin_time, CASE transaction_type WHEN 1 THEN 'Read/write transaction' WHEN 2 THEN 'Read-only transaction' WHEN 3 THEN 'System transaction' WHEN 4 THEN 'Distributed transaction' END tran_type, CASE transaction_state WHEN 0 THEN 'not been completely initialized yet' WHEN 1 THEN 'initialized but not started' WHEN 2 THEN 'active' WHEN 3 THEN 'ended (read-only transaction)' WHEN 4 THEN 'commit initiated for distrubuted transaction' WHEN 5 THEN 'transaction prepared and waiting resolution' WHEN 6 THEN 'committed' WHEN 7 THEN 'being rolled back' WHEN 8 THEN 'been rolled back' END tran_state FROM sys.dm_tran_active_transactions WHERE transaction_id = 47941-- 这个查询返回了事务开始时间、事务类型以及事务状态: ----------------------------------------------------------------------------------------- transaction_begin_time tran_type tran_state 2010-08-13 11:19:08.750 Read/write transaction active ------------------------------------------------------------------------------------------- 解析 -- 这个技巧演示了如何使用各种DMV来排除故障和调查长时间运行的活动事务。你决定使用哪些列取决于你要排除什么故障。在这个场景中,我使用如下的故障排除步骤: -- *1) 查询 sys.dm_tran_session_transactions 来显示会话ID和事务ID(各个事务的标识符)之间的映射; -- *2) 查询 sys.dm_exec_connections 和 sys.dm_exec_sql_text 来查找会话最新执行的命令(引用 most_recent_sql_handle 列); -- *3) 最后,查询sys.dm_tran_active_transactions来确定事务被打开了多长时间、事务的类型以及事务的状态。-- 使用这个故障排除技术可以回到应用程序去查明查询调用的被抛弃的事务(打开但从未提交),以及那些运行时间太长或对于应用程序来说是不必要的不恰当事务。
-- 这个技巧演示了如何找出更多活动事务的信息。为了进行演示,将描述一个常见的场景:你的应用程序会遇到很多高持时间的阻塞。
-- 你被告知这个应用程序经常在每个查询之前打开显式的事务。-- 为了说明这个场景,将执行如下的SQL(表示应用程序代码引发了并发性问题):SET TRANSACTION ISOLATION LEVEL SERIALIZABLEBEGIN TRANSELECT *
FROM HumanResources.DepartmentINSERT HumanResources.Department
(Name, GroupName)
VALUES('Test','OA')-- 在另一个/新的SQL Server Management Studio 查询窗口,通过查询sys.dm_tran_session_transactions动态管理视图(DMV)来识别所打开的事务:SELECT session_id, transaction_id, is_user_transaction, is_local
FROM sys.dm_tran_session_transactions
WHERE is_user_transaction = 1-- 这个查询返回如下内容(你实际的会话ID和事务ID会有所不同):
-----------------------------------------------------------------------------------------
session_id transaction_id is_user_transaction is_local
54 47941 1 1
------------------------------------------------------------------------------------------- 现在有会话ID可以使用了,可以通过查询 sys.dm_exec_connections 和 sys.dm_exec_sql_text 来挖掘最近执行的查询的详细信息:SELECT s.text
FROM sys.dm_exec_connections c
CROSS APPLY sys.dm_exec_sql_text(c.most_recent_sql_handle) s
WHERE session_id = 54-----------------------------------------------------------------------------------------
text
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE BEGIN TRAN SELECT * FROM HumanResources.Department INSERT HumanResources.Department (Name, GroupName) VALUES('Test','OA')
------------------------------------------------------------------------------------------- 因为也从对sys.dm_tran_session_transactions 的第一个查询中得到了事务的ID,所以可以使用sys.dm_tran_active_transactions 来了解更多事务本身的内容:SEELCT transaction_begin_time,
CASE transaction_type
WHEN 1 THEN 'Read/write transaction'
WHEN 2 THEN 'Read-only transaction'
WHEN 3 THEN 'System transaction'
WHEN 4 THEN 'Distributed transaction'
END tran_type,
CASE transaction_state
WHEN 0 THEN 'not been completely initialized yet'
WHEN 1 THEN 'initialized but not started'
WHEN 2 THEN 'active'
WHEN 3 THEN 'ended (read-only transaction)'
WHEN 4 THEN 'commit initiated for distrubuted transaction'
WHEN 5 THEN 'transaction prepared and waiting resolution'
WHEN 6 THEN 'committed'
WHEN 7 THEN 'being rolled back'
WHEN 8 THEN 'been rolled back'
END tran_state
FROM sys.dm_tran_active_transactions
WHERE transaction_id = 47941-- 这个查询返回了事务开始时间、事务类型以及事务状态:
-----------------------------------------------------------------------------------------
transaction_begin_time tran_type tran_state
2010-08-13 11:19:08.750 Read/write transaction active
------------------------------------------------------------------------------------------- 解析
-- 这个技巧演示了如何使用各种DMV来排除故障和调查长时间运行的活动事务。你决定使用哪些列取决于你要排除什么故障。在这个场景中,我使用如下的故障排除步骤:
-- *1) 查询 sys.dm_tran_session_transactions 来显示会话ID和事务ID(各个事务的标识符)之间的映射;
-- *2) 查询 sys.dm_exec_connections 和 sys.dm_exec_sql_text 来查找会话最新执行的命令(引用 most_recent_sql_handle 列);
-- *3) 最后,查询sys.dm_tran_active_transactions来确定事务被打开了多长时间、事务的类型以及事务的状态。-- 使用这个故障排除技术可以回到应用程序去查明查询调用的被抛弃的事务(打开但从未提交),以及那些运行时间太长或对于应用程序来说是不必要的不恰当事务。