Как отслеживать изменения уровня изоляции транзакций в SQL Profiler или любом другом инструменте
Я успешно только смог увидеть transaction isolation level
события в Audio Login
событие. Существуют ли другие способы мониторинга transaction isolation level
изменения с помощью SQL Profiler или с помощью какого-либо другого инструмента? Причина, по которой я спрашиваю, заключается в том, что SQL Profiler не может выводить события в правильном порядке или пропускает события, потому что при установке IsolationLevel
в Serializable
в моем приложении это все еще показывает transaction isolation level read committed
,
пример Audit Login
в SQL Profiler:
-- network protocol: Named Pipes
set quoted_identifier on
set arithabort off
set numeric_roundabort off
set ansi_warnings on
set ansi_padding on
set ansi_nulls on
set concat_null_yields_null on
set cursor_close_on_commit off
set implicit_transactions off
set language us_english
set dateformat mdy
set datefirst 7
set transaction isolation level serializable
1 ответ
Я боюсь, что нет ни одного.
Даже если бы он был один, что бы вы хотели увидеть, когда в объединении запрашивалось несколько таблиц, и у одной или нескольких из них была NOLOCK, которая считывается незафиксированной?
Профилировщик сообщает о запросах на уровне операторов, а не на уровне таблиц, поэтому у вас может быть сочетание уровней изоляции транзакций (это верно для профилировщика и расширенных событий)
Лучшее, что вы можете сделать, - это вручную проанализировать начало оператора (пакет и процедура) и найти заданный уровень изоляции транзакции.
издание
Я нашел этот вопрос, пытаясь определить, почему Entity Framework подключается к нашей базе данных с уровнем изоляции сериализуемой транзакции. Как указывалось в исходном ответе, нет прямого способа сбора этих данных ни из трассировки SQL, ни из расширенных событий.
Ниже приведен запрос для повторного сбора уровней изоляции транзакций из DMVsys.dm_exec_sessions и sys.dm_exec_requests. Таблицы будут быстро расти, но они полезны для краткого отслеживания уровней изоляции от внешних приложений:
SET NOCOUNT ON
IF OBJECT_ID('dbo.Query', 'U') IS NOT NULL DROP TABLE dbo.Query
IF OBJECT_ID('dbo.SessionData', 'U') IS NOT NULL DROP TABLE dbo.SessionData
GO
CREATE TABLE dbo.Query
(
SessionID INT
,StartTime DATETIME
,IsolationLevel INT
,IsolationLevelName VARCHAR(20)
,ObjectName VARCHAR(300)
,StatementText VARCHAR(MAX)
,QueryPlan XML
)
CREATE TABLE dbo.SessionData
(
SessionID INT
,LoginTime DATETIME
,IsolationLevel INT
,IsolationLevelName VARCHAR(20)
,ProgramName VARCHAR(300)
,LoginName VARCHAR(300)
)
WHILE 1=1
BEGIN
INSERT INTO dbo.Query
SELECT
SessionID = req.session_id
,StartTime = req.start_time
,IsolationLevel = req.transaction_isolation_level
,IsolationLevelName =
CASE req.transaction_isolation_level
WHEN 1 THEN 'Read Uncomitted'
WHEN 2 THEN 'Read Committed'
WHEN 3 THEN 'Repeatable Read'
WHEN 4 THEN 'Serializable'
WHEN 5 THEN 'Snapshot'
ELSE 'Unknown' END
,ObjectName = OBJECT_NAME(st.objectid, st.[dbid])
,StatementText = SUBSTRING
(REPLACE
(REPLACE
(SUBSTRING
(ST.[text]
, (req.statement_start_offset/2) + 1
, (
(CASE statement_end_offset
WHEN -1
THEN DATALENGTH(st.[text])
ELSE req.statement_end_offset
END
- req.statement_start_offset)/2) + 1)
, CHAR(10), ' '), CHAR(13), ' '), 1, 512)
, QueryPlan = qp.query_plan
FROM sys.dm_exec_requests req
CROSS APPLY sys.dm_exec_sql_text(req.[sql_handle]) st
CROSS APPLY sys.dm_exec_query_plan(req.plan_handle) qp
WHERE ST.[text] NOT LIKE N'%INSERT INTO dbo.Query%'
INSERT dbo.SessionData
SELECT
SessionID = session_id
,LoginTime = login_time
,IsolationLevel = transaction_isolation_level
,IsolationLevelName =
CASE transaction_isolation_level
WHEN 1 THEN 'Read uncomitted'
WHEN 2 THEN 'Read committed'
WHEN 3 THEN 'Repeatable read'
WHEN 4 THEN 'Serializable'
ELSE 'Unknown' END
,ProgramName = [program_name]
,LoginName = login_name
FROM sys.dm_exec_sessions
WHERE security_id <> 0x01
AND session_id <> @@SPID
END
SELECT *
FROM dbo.Query
SELECT *
FROM dbo.SessionData