2011-01-07 72 views
14

我目前有關於TransactionScope對象的構造函數的混淆。TransactionScopeOption - 必需或需要新的

說我的網站的用戶可以訂購產品。在提交他們的請求時,我對剩餘的當前數量進行驗證,如果它仍然大於零,我執行請求。然後,最後我減少剩下的當前數量。

整個過程在一個事務中,使用.NET transactionScope。

在閱讀了關於.NET transactionScope對象的幾篇文章之後,我現在對用於transactionScope的構造函數的TransactionScopeOption的值感到困惑。

下列哪一個更適合於上述情況:

public void ProcessRequest() 
{ 
    TransactionOptions transactionOptions = new TransactionOptions(); 
    transactionOptions.IsolationLevel = IsolationLevel.Serializable; 
    using (TransactionScope currentScope = new TransactionScope(TransactionScopeOption.RequiresNew, transactionOptions)) { 
     // DB Query to verify if quantity is still greater than zero 
     // DB Query to request and decrement quantity 
     currentScope.Complete(); 
    } 
} 

OR

public void ProcessRequest() 
{ 
    TransactionOptions transactionOptions = new TransactionOptions(); 
    transactionOptions.IsolationLevel = IsolationLevel.Serializable; 
    using (TransactionScope currentScope = new TransactionScope(TransactionScopeOption.Required, transactionOptions)) { 
     // DB Query to verify if quantity is still greater than zero 
     // DB Query to request and decrement quantity 
     currentScope.Complete(); 
    } 
} 

注意的是,以上只是一個在我的實際問題簡化。我只想知道這種情況下TransactionScopeOption的正確值(RequiresNew必需)。

感謝您的回覆。

回答

16

這取決於你想要什麼發生,如果其他方法調用ProcessRequest另一個事務內:

public void SomeOtherMethod() { 
    using (TransactionScope ts = new TrasansctionScope()) { 
     // Another DB action 
     ProcessRequest(); 
     // Yet another DB action 
    } 
} 

如果你想通過ProcessRequestSomeOtherMethod使用創建的事務,使用TransactionScope.Required。這是默認的(當你調用它時,它仍然創建一個事務,而不會在調用堆棧上創建另一個事務範圍)。

如果您希望強制此方法始終使用自己的(新)事務,請使用TransactionScope,RequiresNew

+0

在我的情況下,ProcessRequest本身的方法永遠不會參與另一個事務。 我只希望保證請求執行後: 「DB查詢,以驗證是否量仍大於零」 由它執行時間: 「DB查詢請求和遞減量」 由於另一個請求,數量尚未達到零,執行相同的方法ProcessRequest。 所以,我猜默認值:TransactionScope.Required對我來說是正確的值。 – 2011-01-07 19:37:41

5

我知道你的方法不會在另一個事務中調用。但萬一它會,這裏是你如何選擇TransactionScopeOption

如果通過的ProcessRequest寫入數據庫中的內容不能由任何呼叫者被推翻,則使用RequiresNew,啓動一個新的事務平行於由呼叫者(如果有的話)產生的一個,並且所述新的事務不被管理來電者通過任何方式。 最好認爲事務不能嵌套,要麼使用現有事務,要麼創建一個新事務。交易不嵌套!

如果通過ProcessRequest寫入數據庫的內容可以被推翻,請使用Required。但是,這個選項並不透明。調用者必須意識到ProcessRequest可能會回滾,因爲如果被調用者回滾環境事務,調用者將無法執行任何SQL操作,否則會發生異常「操作對事務狀態無效」。將被拋出。在運行任何查詢之前,最好始終檢查System.Transactions.Transaction.Current.TransactionInformation.Status,因爲您不知道任何被調用者是否偷偷創建了事務並將其回滾。

您可能會發現下表很有用。 enter image description here