2010-01-04 51 views
10

TransactionScope期望按如下方式調用其Complete方法。否則,交易將不會被提交。爲什麼TransactionScope不會成功?

using(TransactionScope scope = new TransactionScope()) 
{ 
    /* Perform transactional work here */ 

    scope.Complete(); 
} 

那麼假設成功的實現更合適嗎?這意味着在標準情況下(成功)將需要更少的代碼。

在異常或呼叫給方法的情況下爲「回滾」(該方法目前不存在),例如事務可以被回滾。

using(TransactionScope scope = new TransactionScope()) 
{ 
    /* Perform transactional work here */ 

    if(problemOccurred) 
    { 
     scope.Rollback(); 
    } 
} 

請注意,只有在問題未導致異常的情況下,纔會需要problemOccurred標誌。在這種情況下,回滾將自動執行。

我感興趣的獲得進一步瞭解爲什麼使用此實施。

更新:迄今爲止的一些答案認爲,如果使用我描述的實現,則需要try-catch塊。不是這種情況。當在使用塊中未處理異常時,事務自動回滾。現有的實施和我描述的都是這種情況。有關更多詳細信息,請參閱「完成交易範圍」部分here

更新2:我終於明白髮生了什麼的答案被解釋。這不是一種語言結構,它可以用語言設計者認爲合適的任何方式進行解釋 - 它是IDisposable模式的實現。如果沒有調用完成Dispose方法內的代碼,則不知道它是否被調用,因爲正在成功執行using塊中的代碼或發生異常。我想象的事物和回滾都是關鍵字。

transaction 
{ 
    /* Perform transactional work here */ 

    if(problemOccurred) 
    { 
     rollback; 
    } 
} 

如果事務選項需要傳遞給TransactionScope,這當然會出現問題。

+3

爲什麼不是我的評論自動添加當我改變頁面,我不應該單擊[添加評論] ... – cjk 2010-01-04 13:20:37

+1

從更新 - * *機制,通過該交易在例外的臉回滾是你在不調用Commit的情況下到達使用塊的末尾。即該行爲取決於您要刪除的確切功能。 – 2010-01-04 14:12:55

+0

你的「更新」是指當前的遊戲狀態 - 如果TransactionScope假定成功,你會改變這種情況。 – 2010-01-04 14:15:01

回答

14

這意味着你不需要把一個手動嘗試/最後(或捕捉)塊(可能帶有「成功」標誌)的失敗案例。嘗試重寫上面的代碼回滾的錯誤,看看它是多麼混亂......

基本上正常期望的行爲是如果達到,沒有例外塊結束時僅提交。實現這一目標的最簡單方法是在塊的末尾放置一個方法調用來表示成功。

+0

我不認爲需要嘗試塊 - 請參閱我在回答中的評論... http://stackoverflow.com/questions/1999461/why-doesnt-transactionscope-assume-success/1999475#1999475 你同意嗎? – 2010-01-04 13:51:23

+1

不,因爲你提出*改變*這種行爲。 *當前*由於您所抱怨的行爲,您不需要try/catch塊 - 除非您明確提交,否則將會失敗。 – 2010-01-04 14:14:20

4

如果選擇了其他實現,那麼人們會問這個相反的問題!

儘管如此,在一個旨在保護部分或不正確更新的機制中的默認行爲必然是而不是要提交,不是嗎?

15

這樣一來,每一筆交易是這樣的:

using(TransactionScope scope = new TransactionScope()) 
{ 
    try 
    { 
    /* Perform transactional work here */ 
    } 
    catch (Exception) 
    { 
    scope.Rollback(); 
    throw; 
    } 
} 

這是更多的代碼。

編輯:

其他的都是有風險或不良作風。 你必須絕對確保提交時有沒有任何錯誤。當離開使用塊時,您不知道是否因爲拋出異常而拋棄它,或者因爲剛到達它的末尾。當你撥打Complete時,你知道。

的事務塊語法已經是你可以做的最簡單。只需在沒有任何特殊錯誤處理的情況下執行事務,並在最後提交它。出現任何錯誤時,您不必關心和回滾。考慮一下,幾乎每一行代碼都會拋出異常(例如,NullReference,Overflows,InvalidOperation等)。那麼比這更容易的是什麼?

+1

如果使用scope.Complete()方法,如果出現回滾,何時會發生回滾? – DOK 2010-01-04 13:30:54

+1

TransactionScope使用塊內的異常會自動回滾事務。這裏除了MSDN以外。 「無法調用此方法會中止事務,因爲事務管理器將此解釋爲系統故障,或等同於事務範圍內引發的異常。「 你try塊是多餘的。 – 2010-01-04 13:45:41

+0

這裏是除的鏈接。 http://msdn.microsoft.com/en-us/library/ms172152.aspx – 2010-01-04 13:55:26

3

我覺得寫的代碼量成功的,因爲@喬恩飛碟雙向說,少(少醜)目前的方式。從一個交易點,但是,我想你會悲觀,並認爲除非成功是明確指出,你會回滾。在我看來,提交錯誤交易是一個非常糟糕的問題,而不是由於代碼錯誤而意外無法成功執行交易。