2008-10-21 85 views
6

考慮下面的SQL:SQL Server中嵌套事務的隔離範圍是什麼?

 
BEGIN TRAN 
SET TRANSACTION ISOLATION LEVEL READ COMMITTED 

INSERT Bands 
    ( Name ) 
SELECT 'Depeche Mode' 
UNION 
SELECT 'Arcade Fire' 

    -- I've indented the inner transaction to make it clearer. 

    BEGIN TRAN 
    SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED 

    SELECT * 
     FROM Bands 

    COMMIT 

-- What is the isolation level right here? 

UPDATE Bands 
    SET Name = 'Modest Mouse' 
WHERE Name = 'Oddest House' 

COMMIT 

總之,我們啓動一個事務,並設置其隔離級別設置爲READ COMMITTED。然後,我們執行一些隨機SQL並啓動另一個嵌套事務。在此交易中,我們將隔離級別更改爲READ UNCOMMITTED。然後,我們承諾交易並返回其他交易。

現在,我的猜測是,內部提交後,隔離級別返回到READ COMMITTED。它是否正確?

回答

7

我不認爲這是正確的。

參考這裏的言論:Set Transaction

只有隔離級別 選項都可以在同一時間內設定的一個,它 保持設置爲連接,直到 被明確改變。

+0

這是正確的,我剛剛用sp_lock – 2008-10-21 21:33:15

7

您[Bob Probst]是正確的。有趣的是,根據documentation你鏈接:

如果發出事務隔離級別設置在存儲過程或觸發器,當對象返回控制的隔離級別復位到水平的影響被調用的對象時。例如,如果您在批處理中設置REPEATABLE READ,然後批處理會調用將隔離級別設置爲SERIALIZABLE的存儲過程,則當存儲過程將控制權返回給批處理時,隔離級別設置將恢復爲REPEATABLE READ。

所以,這裏的底線是,SET事務隔離級別已程序親和力,不交易親和力(我原以爲)。

太棒了!

+2

進行了測試那麼糟糕,哈哈!我的C#數據庫API傾向於接受打開的連接對象,所以我可以調用多個函數而不必每次都打開一個新的連接。這種「事務關聯性」的缺乏意味着如果我從另一個數據庫API方法中調用一個數據庫API方法,並且都使用事務,則嵌套事務可能會改變調用方事務的事務隔離級別。肯定很糟糕。替代方法...對於使用事務的任何C#方法,通過在返回之前保存隔離級別(dbcc useroptions)並將其恢復,爲C#事務處理C#代碼模擬過程關聯! – Triynko 2009-08-30 04:49:06