2015-02-06 19 views
4

我讀到關於C#中的交易範圍和它的工作原理是這樣的:如何做一個像'TransactionScope'的代碼工作?

using (connectionDb) 
{ 
    connectionDb.Open(); 
    using (var ts = new System.Transactions.TransactionScope()) 
    { <-- 
     try 
     { 
      connectionDb.ExecuteNonQuery(); 
      ts.Complete(); 
     } 
     catch (Exception) 
     { 
      throw; 
     } 
     finally 
     { } 
    } <-- 
} 

每一個條款中使用括號工作在相同的交易,但我不明白的代碼是如何確定的databasecommand是在範圍上運行而不傳遞事務範圍參數既不打開連接,也不執行查詢。

舉例來說,如果我有以下代碼:

var myObject = new MyObject(); 
var childObject = new ChildObject(); 
childObject.Foo(myObject); 
childObject.Bar(myObject); 

我可以爲變量創建myObject並使用到childObject方法,而通過參數傳給她一個範圍?像這樣:

using(var myObject = new MyObject()) 
{ 
    childObject.Foo(); -- Here the method use the variable myObject 
    childObject.Bar(); -- Here the method use the variable myObject 
} 

回答

7

當你創建一個TransactionScope時,它存儲在線程本地存儲中保存的靜態變量Transaction.Current中。與事務交互的方法查看此變量以確定它們所處的事務。這稱爲環境事務。

+2

只需使用ThreadStatic屬性標記您的靜態。 – Jessica 2015-02-06 11:43:52

+0

我不知道這個ThreadStatic屬性,因爲這個。它是一個非常有用的命令。 – 2015-02-06 11:52:27

+2

@OnlyaCuriousMind注意'ThreadStatic',但它有一些注意事項。例如,如果您要分配一個默認值,它將只用於導致靜態構造函數運行的第一個線程 - 其他線程將使其爲空(空/默認) – Luaan 2015-02-06 12:05:56

1

您的示例顯示了環境事務。在數據庫連接之下,數據庫連接檢測到你已經啓動了一個事務並且將會登錄到它。更多的進程可以進入該事務(例如MSMQ事務消息傳遞),以便在觸發回滾的條件滿足時,每個其他入伍進程都可以啓動回滾。根據您選擇的隔離級別,它也會對數據應用更積極的鎖定。 1

您的第二位代碼將會限定您定義的對象,但用例不同。你仍然必須做這樣的事情:

using(var myObject = new MyObject()) 
{ 
    childObject.Foo(myObject); -- Here the method use the variable myObject 
    childObject.Bar(myObject); -- Here the method use the variable myObject 
} 

這是什麼給你是終生的管理,在樣板代碼的減少,比如不必調用手動配置,這樣的東西。

+0

看看傑西卡的答案。 – 2015-02-06 11:53:25

相關問題