SQL Server 2005的事务级别和存储过程

3
如果我使用命令 SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED,然后在同一上下文中执行一个存储过程,那么存储过程会使用之前指定的事务级别还是将使用默认级别?
如果我想强制每个存储过程都使用一个事务级别,我是否必须在代码顶部包含相同的语句 (SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED)?
注:该系统基于 .NET 2.0 和专有的第三方产品,并存在一些限制,因此需要这些解决方案。
1个回答

12

存储过程将使用调用时生效的事务隔离级别。

如果存储过程本身设置了显式的隔离级别,则在存储过程退出时将重置该级别。

(编辑:刚刚检查发现这与 BOL 所说的相反 "... 它仍然设置为该连接,直到明确更改",但可以从下面看出)

CREATE PROC CheckTransLevel
AS
DECLARE @Result varchar(20)

SELECT @Result = CASE transaction_isolation_level 
                        WHEN 0 THEN 'Unspecified' 
                        WHEN 1 THEN 'ReadUncomitted' 
                        WHEN 2 THEN 'Readcomitted' 
                        WHEN 3 THEN 'Repeatable' 
                        WHEN 4 THEN 'Serializable' 
                        WHEN 5 THEN 'Snapshot' 
                  END 
FROM sys.dm_exec_sessions 
WHERE session_id = @@SPID

PRINT @Result

GO
CREATE PROC SetRCTransLevel
AS
PRINT 'Enter: SetRCTransLevel'
SET TRANSACTION ISOLATION LEVEL READ COMMITTED
EXEC CheckTransLevel
PRINT 'Exit: SetRCTransLevel'
GO

SET NOCOUNT ON

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

EXEC CheckTransLevel

EXEC SetRCTransLevel

EXEC CheckTransLevel

结果
ReadUncomitted
Enter: SetRCTransLevel
Readcomitted
Exit: SetRCTransLevel
ReadUncomitted

+1 这让我大吃一惊... 我本来以为我看到的 SQL Server 是按照 BOL 所说的那样运行的;我遇到了一个问题,其中一个存储过程将隔离级别提升到了可串行化,然后其他存储过程受到了影响,但我猜可能是应用程序保持了该隔离级别而不是 SQL Server。 - Michael Fredrickson
文档实际上描述了这种行为(不幸的是,在稍后的段落中,它可能已经在此期间添加了约6.5年):如果您在存储过程或触发器中发布SET TRANSACTION ISOLATION LEVEL语句,则当对象返回控制时,隔离级别将被重置为在调用对象时生效的级别。 - Taudris

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