2013-04-18 24 views
5

請考慮以下方法。TransactionScope隱式應用,直到明確完成?

DoA() 
{ 
    using (TransactionScope scope = new TransactionScope) 
    { 
    using (SqlConnection connection = new SqlConnection(connectionString)) 
    { 
     connection.Open(); 
     SqlCommand command = new SqlCommand(query, connection); 
     command.ExecuteNonReader(); 

     DoB();  

     scope.Complete(); 
    } 
    } 
} 

DoB() 
{ 
    using (TransactionScope scope = new TransactionScope) 
    { 
    using (SqlConnection connection = new SqlConnection(connectionString)) 
    { 
     connection.Open(); 
     SqlCommand command = new SqlCommand(query, connection); 
     command.ExecuteNonReader(); 

     DoC(); 

     scope.Complete(); 
    } 
    } 
} 

DoC() 
{ 
    using (SqlConnection connection = new SqlConnection(connectionString)) 
    { 
    connection.Open(); 
    SqlCommand command = new SqlCommand(query, connection); 
    command.ExecuteNonReader(); 
    } 
} 

如果我們調用DoA(),做DoB()隨後的相互作用和DoC()運行在DoA()的交易的情況下,因爲它涉及到SQL Server? DoC()是否在DoA()DoB()的事務中運行?

(或者,我嚴重誤解的東西?)

+1

你得到嵌套交易:) – DaveShaw

+0

有一些選項可以控制這一點。請參閱http://msdn.microsoft.com/en-us/library/ms172152(v=vs.85).aspx – AaronLS

+0

中的「使用TransactionScopeOption管理事務流」。注意有關嵌套事務的進一步下行註釋必須按順序使用相同的隔離級別參與環境交易。 – AaronLS

回答

4

所有代碼在邏輯上將是單個事務。嵌套的作用域不一定會創建一個新的事務(除非你使用RequiresNew),所以它將是一個單獨的事務。現在,如果您刪除Complete,每個範圍都必須投票完成事務,以便在第二個範圍內完成該事務,從而導致整個事務回滾。

DoC也將成爲交易的一部分;環境交易將檢測到新的連接並自動登記。

請仔細閱讀所有這些說明在環境事務和不同的選項RequiresRequiresNew,和Suppress招生行爲的細節here

另請注意,如果您的連接不使用完全相同的連接字符串,則會自動將整個事務提升爲分佈式事務。只是要注意的東西。

+0

+1好信息。在我接受之前,你能確認DoC()'和/或'DoB()'在環境'Transaction'中執行了DoC()嗎? (這是我*期望*和*想*發生 - 但要確定。) – svidgen

+0

@svidgen更新了我的答案。 – Andy

+0

美麗。謝謝! – svidgen

2

每安迪的評論編輯:

它好像像這樣的SQL服務器上發生:

BEGIN TRANSACTION A 

    -- do A's work 

    -- B does NOT create a new transaction 

    -- do B's work 

    -- do C's work 

COMMIT TRANSACTION A 

出現以下情況如果new TransactionScope(TransactionScopeOption.RequiresNew)用於DoB()

BEGIN TRANSACTION A 

    -- do A's work 

    BEING TRANSACTION B 

    -- do B's work 

    -- do C's work 

    COMMIT TRANSACTION B 
COMMIT TRANSACTION A 
+0

這不會發生什麼;這將是一筆交易,因爲B中使用的範圍將加入現有的環境交易。如果B沒有投票給「完成」,則整個事務將回滾。 – Andy

+0

@安迪感謝您的澄清。如果使用「新的TransactionScope(TransactionScopeOptions.RequiresNew)」,會發生這種情況嗎? – svidgen

+0

@安迪沒關係,只是看到你的答案! – svidgen