【问题标题】:How to find current transaction level?如何找到当前的交易水平?
【发布时间】:2010-11-05 12:06:24
【问题描述】:

如何在 SQL Server 上找到当前数据库的事务级别?

【问题讨论】:

    标签: sql sql-server sql-server-2008 sql-server-2005 isolation-level


    【解决方案1】:

    运行这个:

    SELECT CASE transaction_isolation_level 
    WHEN 0 THEN 'Unspecified' 
    WHEN 1 THEN 'ReadUncommitted' 
    WHEN 2 THEN 'ReadCommitted' 
    WHEN 3 THEN 'Repeatable' 
    WHEN 4 THEN 'Serializable' 
    WHEN 5 THEN 'Snapshot' END AS TRANSACTION_ISOLATION_LEVEL 
    FROM sys.dm_exec_sessions 
    where session_id = @@SPID
    

    docs.microsoft.com reference for the constant values.

    【讨论】:

    • 如果隔离级别是“read_commited_snapshot”,这个是不准确的。在这种情况下,它只会显示“Readcommited”。
    • @GaTechThomas , READ_COMMITTED_SNAPSHOT 不是隔离级别,它是一个数据库选项,允许在数据库范围内更改 ReadDCommitted 隔离级别的行为
    • @user960567,IIRC,Scott Ivey 的回答会给出这些结果。
    • @zzzeek - 这就是使用已经过时 12 年的数据库所得到的结果。
    • 我理解 READ COMMITTED SNAPSHOT 的技术性不是它自己独特的隔离级别,但它会抓住人们并确实抓住了我。在示例开始之前,MS 本身也在本页下方显示的 TABLE 中将其声明为隔离级别,因此可以通过更加务实并符合 MS 评论docs.microsoft.com/en-us/sql/t-sql/statements/… 来改进这个答案
    【解决方案2】:

    只要运行DBCC useroptions,你就会得到这样的结果:

    Set Option                  Value
    --------------------------- --------------
    textsize                    2147483647
    language                    us_english
    dateformat                  mdy
    datefirst                   7
    lock_timeout                -1
    quoted_identifier           SET
    arithabort                  SET
    ansi_null_dflt_on           SET
    ansi_warnings               SET
    ansi_padding                SET
    ansi_nulls                  SET
    concat_null_yields_null     SET
    isolation level             read committed
    

    【讨论】:

    • 它在活动时指出“读取提交的快照”(参见 RC 快照与锁定),至少在 SQL Server 2008 上
    【解决方案3】:
    SELECT CASE  
              WHEN transaction_isolation_level = 1 
                 THEN 'READ UNCOMMITTED' 
              WHEN transaction_isolation_level = 2 
                   AND is_read_committed_snapshot_on = 1 
                 THEN 'READ COMMITTED SNAPSHOT' 
              WHEN transaction_isolation_level = 2 
                   AND is_read_committed_snapshot_on = 0 THEN 'READ COMMITTED' 
              WHEN transaction_isolation_level = 3 
                 THEN 'REPEATABLE READ' 
              WHEN transaction_isolation_level = 4 
                 THEN 'SERIALIZABLE' 
              WHEN transaction_isolation_level = 5 
                 THEN 'SNAPSHOT' 
              ELSE NULL
           END AS TRANSACTION_ISOLATION_LEVEL 
    FROM   sys.dm_exec_sessions AS s
           CROSS JOIN sys.databases AS d
    WHERE  session_id = @@SPID
      AND  d.database_id = DB_ID();
    

    【讨论】:

    • 还请详细说明代码以更具教育意义。
    【解决方案4】:
    DECLARE   @UserOptions TABLE(SetOption varchar(100), Value varchar(100))
    DECLARE   @IsolationLevel varchar(100)
    
    INSERT    @UserOptions
    EXEC('DBCC USEROPTIONS WITH NO_INFOMSGS')
    
    SELECT    @IsolationLevel = Value
    FROM      @UserOptions
    WHERE     SetOption = 'isolation level'
    
    -- Do whatever you want with the variable here...  
    PRINT     @IsolationLevel
    

    【讨论】:

    • +1 因为它在与已提交读一起使用时也会打印“快照”(而不是默认的共享锁机制)
    • 这太过分了,按照 thiagoh 说的做 DBCC USEROPTIONS
    【解决方案5】:

    如果您谈论的是当前事务嵌套级别,那么您将使用@@TRANCOUNT

    如果您在谈论事务隔离级别,请使用DBCC USEROPTIONS 并查找隔离级别的选项。如果未设置,则已提交读取

    【讨论】:

    • 另外请记住,DBCC USEROPTIONS 是查找 SESSION 隔离级别的绝佳选择,但它可能会很棘手 - 如果您的代码更改每个事务的隔离级别,那么隔离级别为与会话默认值不同可能很难捕获。例如,如果您使用隔离级别 x 打开会话,但在会话中的特定事务的持续时间内将隔离级别更改为 y,则如果在该事务之外调用 DBCC USEROPTIONS 将不会让您看到。跨度>
    • 在 SQL Server 2012 中,DBCC USEROPTIONS 的“隔离级别”设置为“已提交读”
    【解决方案6】:
    SELECT CASE  
        WHEN transaction_isolation_level = 0 THEN 'Unspecified' 
        WHEN transaction_isolation_level = 1 THEN 'Read Uncommitted' 
        WHEN transaction_isolation_level = 2 AND d.snapshot_isolation_state_desc = 'OFF' THEN 'Read Committed' 
        WHEN transaction_isolation_level = 2 AND d.snapshot_isolation_state_desc = 'ON' AND d.is_read_committed_snapshot_on = 1 THEN 'Snapshot Read Committed'  
        WHEN transaction_isolation_level = 2 AND d.snapshot_isolation_state_desc = 'ON' AND d.is_read_committed_snapshot_on = 0 THEN 'Snapshot'  
        WHEN transaction_isolation_level = 3 THEN 'Repeatable Read' 
        WHEN transaction_isolation_level = 4 THEN 'Serializable' END AS TRANSACTION_ISOLATION_LEVEL,
        d.is_read_committed_snapshot_on,
        d.snapshot_isolation_state_desc
    FROM sys.dm_exec_sessions 
           CROSS JOIN sys.databases AS d
    where session_id = @@SPID
      AND  d.database_id = DB_ID();
    

    【讨论】:

    • 您的回答与 7 年前发布的 this answer 几乎没有什么不同。您应该 edit 您的答案包含有关您的解决方案的更多详细信息和/或对如何此代码块回答问题的说明。这有助于提供上下文,并使您的答案对未来的读者更有用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-10-07
    • 2020-09-17
    • 2019-10-26
    • 1970-01-01
    • 2023-02-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多