Как отслеживать изменения уровня изоляции транзакций в 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