TransactionScope是.Net Framework 2.0滯后,新增了一個名稱空間。它的用途是為數據庫訪問提供了一個“輕量級”[區別于:SqlTransaction]的事務。使用之前必須添加對 System.Transactions.dll 的引用。
下列代碼就是一個正在創建的事務,這個事務自身還封裝了多個數據庫查詢。只要任意一個 SqlCommand 對象引發異常,程序流控制就會跳出 TransactionScope 的 using 語句塊,隨后,TransactionScope 將自行釋放并回滾該事務。由于這段代碼使用了 using 語句,所以 SqlConnection 對象和 TransactionScope 對象都將被自動調用Dispose()釋放。由此可見,只需添加很少的幾行代碼,您就可以構建出一個事務模型,這個模型可以對異常進行處理,執行結束后會 自行清理,此外,它還可以對命令的提交或回滾進行管理。
//創建TransactionScope
using (TransactionScope tsCope= new TransactionScope())
{
using (SqlConnection cn2005= new SqlConnection(someSql2005))
{
SqlCommand cmd= new SqlCommand(sqlUpdate, cn2005);
cn2005.Open();
cmd.ExecuteNonQuery();
}
using (SqlConnection cn2005= new SqlConnection(anotherSql2005))
{
SqlCommand cmd= new SqlCommand(sqlDelete, cn2005);
cn2005.Open();
cmd.ExecuteNonQuery();
}
tsCope.Complete();
}
連接字符串關鍵字(Enlist)
SqlConnection.ConnectionString 屬性支持關鍵字 Enlist,該關鍵字指示 System.Data.SqlClient 是否將檢測事務上下文并自動在分布式事務中登記連接。 如果 Enlist=true,連接將自動在打開的線程的當前事務上下文中登記。 如果 Enlist=false,SqlClient 連接不會與分布式事務進行交互。 Enlist 的默認值為 true。 如果連接字符串中未指定 Enlist,若在連接打開時檢測到一個,連接將自動在分布式事務中登記。
Server=(local)SQL2005;Database=Northwind;Integrated Security=SSPI;enlist=false
上面所看到的示例中我們使用了TransactionScope的默認設置。TransactionScope有三種模式: TransactionScopeOptions
描述
Required
如果已經存在一個事務,那么這個事務范圍將加入已有的事務。否則,它將創建自己的事務。
RequiresNew
這個事務范圍將創建自己的事務。
Suppress
如果處于當前活動事務范圍內,那么這個事務范圍既不會加入氛圍事務 (ambient transaction),也不會創建自己的事務。當部分代碼需要留在事務外部時,可以使用該選項。
您可以在代碼的任何位置上隨是查看是否存在事務范圍,具體方法就是查看 System.Transactions.Transaction.Current 屬性。如果這個屬性為“null”,說明不存在當前事務。
若要更改 TransactionScope 類的默認設置,您可以創建一個 TransactionOptions 對象,然后通過它在 TransactionScope 對象上設置隔離級別和事務的超時時間。TransactionOptions 類有一個 IsolationLevel 屬性,通過這個屬性可以更改隔離級別,例如從默認的可序列化 (Serializable) 改為ReadCommitted,甚至可以改為 SQL Server 2005 引入的新的快照 (Snapshot) 級別。(請記住,隔離級別僅僅是一個建議。大多數數據庫引擎會試著使用建議的隔離級別,但也可能選擇其他級別。)此 外,TransactionOptions 類還有一個 TimeOut 屬性,這個屬性可以用來更改超時時間(默認設置為 1 分鐘)。
下列代碼中使用了默認的 TransactionScope 對象及其默認構造函數。也就是說,它的隔離級別設置為可序列化 (Serializable),事務的超時時間為 1 分鐘,而且 TransactionScopeOptions 的設置為 Required。
TransactionOptions tOpt= new TransactionOptions();
//設置TransactionOptions模式
tOpt.IsolationLevel= IsolationLevel.ReadCommitted;
// 設置超時間隔為2分鐘,默認為60秒
tOpt.Timeout= new TimeSpan(0,2,0);
string cnString= ConfigurationManager.ConnectionStrings["sql2005DBServer"].ConnectionString);
using (TransactionScope tsCope= new TransactionScope(TransactionScopeOption.RequiresNew, tOpt))
{
using (SqlConnection cn2005= new SqlConnection(cnString)
{
SqlCommand cmd= new SqlCommand(updateSql1, cn2005);
cn2005.Open();
cmd.ExecuteNonQuery();
}
tsCope.Complete();
}
嵌套應用
如下列代碼,假設 Method1 創建一個 TransactionScope,針對一個數據庫執行一條命令,然后調用 Method2。Method2 創建一個自身的 TransactionScope,并針對一個數據庫執行另一條命令。
private void Method1()
{
using (TransactionScope ts=
new TransactionScope(TransactionScopeOption.Required))
{
using (SqlConnection cn2005= new SqlConnection())
{
SqlCommand cmd= new SqlCommand(updateSql1, cn2005);
cn2005.Open();
cmd.ExecuteNonQuery();
}
Method2();
ts.Complete();
}
}
private void Method2()
{
using (TransactionScope ts=
new TransactionScope(TransactionScopeOption.RequiresNew))
{
using (SqlConnection cn2005= new SqlConnection())
{
SqlCommand cmd= new SqlCommand(updateSql2, cn2005);
cn2005.Open();
cmd.ExecuteNonQuery();
}
ts.Complete();
}
}
總結:
進入和退出事務都要快,這一點非常重要,因為事務會鎖定寶貴的資源。最佳實踐要求我們在需要使用事務之前再去創建它,在需要對其執行命令前迅速打開連接, 執行動作查詢 (Action Query),并盡可能快地完成和釋放事務。在事務執行期間,您還應該避免執行任何不必要的、與數據庫無關的代碼,這能夠防止資源被毫無疑義地鎖定過長的 時間。 使用注意:TransactionScope事務需要開啟一些服務,(如果數據庫不在本地,服務器和客戶端都需要開啟以下服務和組件服務)

以下組件服務需要開啟
step1

step2:
