如何查找当前事务级别?

201

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

6个回答

317

运行这个:

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

learn.microsoft.com提供的常量值参考


11
如果隔离级别为"read_commited_snapshot",那么这个结果不准确。在这种情况下,它只会显示"Readcommited"。 - GaTechThomas
9
@GaTechThomas,“READ_COMMITTED_SNAPSHOT”不是隔离级别,而是数据库选项,允许在整个数据库范围内更改“Read Committed”隔离级别的行为。 - Gennady Vanin Геннадий Ванин
1
@user960567,如果我没记错的话,Scott Ivey的回答会给出那些结果。 - GaTechThomas
3
你使用一个已经过时十二年的数据库,这就是你所得到的结果。 - Martin Brown
3
我理解“读提交快照”技术并非独立的隔离级别,但它会误导人,我也曾被误导。此外,微软在本页面下方的表格中将其标注为一种隔离级别,而不是在示例开始之后才提到,因此该答案可以更加务实,并符合微软的说明。https://learn.microsoft.com/en-us/sql/t-sql/statements/set-transaction-isolation-level-transact-sql?view=sql-server-ver15 - Alan Macdonald
显示剩余5条评论

72

只需运行 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

1
当“读取提交的快照”处于活动状态时(请参见RC快照与锁定),它会指出至少在SQL Server 2008上。 - user1075613

34
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();

7
请详细说明代码以增加教育性。 - László Papp

26
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也会打印“快照”。 - Shmil The Cat
这太过了,只需要像thiagoh说的那样执行DBCC USEROPTIONS即可。 - user1075613

10
如果您正在谈论当前事务的嵌套级别,则应使用@@TRANCOUNT。如果您在谈论事务隔离级别,请使用DBCC USEROPTIONS并查找隔离级别选项。如果未设置,则为读取已提交

6
请注意,DBCC USEROPTIONS 是查找会话隔离级别的绝佳选项,但它可能有些棘手 - 如果您的代码针对每个事务更改隔离级别,则很难捕获会话默认值不同的时间段。例如,如果您使用隔离级别 x 打开会话,但在会话内的特定事务期间将隔离级别更改为 y,那么在该事务之外调用 DBCC USEROPTIONS 将无法看到这一点。 - DCaugs
1
在SQL Server 2012中,“DBCC USEROPTIONS”的“隔离级别”设置为“读取提交”。 - Gennady Vanin Геннадий Ванин

4
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();

3
你的回答与此答案几乎没有区别,该答案已经发布了7年之久。你应该编辑你的答案,包括更多关于你解决方案的细节和/或解释如何回答这个问题的代码块。这有助于提供上下文,并使你的答案对未来读者更有用。 - Hoppeduppeanut
这个答案不包括当设置快照隔离级别时设置的transaction_isolation_level值为5。因此,在结束之前,需要在CASE语句中添加一个WHEN transaction_isolation_level = 5 THEN 'Snapshot' - Besto

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接