轉自:http://blog.csdn.net/wyxhd2008/article/details/7958423
一、概念
1、在項目中引用using System.Transactions命名空間(先要在添加net組件的引用);
TransactionScope有三種模式:
TransactionScopeOptions
描述
Required
如果已經存在一個事務,那么這個事務范圍將加入已有的事務。否則,它將創建自己的事務。
RequiresNew
這個事務范圍將創建自己的事務。
Suppress
如果處於當前活動事務范圍內,那么這個事務范圍既不會加入氛圍事務 (ambient transaction),也不會創建自己的事務。當部分代碼需要留在事務外部時,可以使用該選項。
進入和退出事務都要快,這一點非常重要,因為事務會鎖定寶貴的資源。最佳實踐要求我們在需要使用事務之前再去創建它,在需要對其執行命令前迅速打開連接, 執行動作查詢 (Action Query),並盡可能快地完成和釋放事務。在事務執行期間,您還應該避免執行任何不必要的、與數據庫無關的代碼,這能夠防止資源被毫無疑義地鎖定過長的 時間。
2、代碼例子:
TransactionOptions transactionOption = new TransactionOptions();
//設置事務隔離級別
transactionOption.IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted;
// 設置事務超時時間為60秒
transactionOption.Timeout = new TimeSpan(0, 0, 60);
using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required, transactionOption))
{
try
{
//在這里實現事務性工作
//發送消息
insertMessage(sendUserId, toUser, content, sendedStatus);
//在接收信息表中插入記錄
receiveCount += insertReceiveMessage(userids[0], sendUserId, content, "0");
// 沒有錯誤,提交事務
scope.Complete();
}
catch (Exception ex) {
throw new Exception("發送信息異常,原因:"+ex.Message);
}finally{
//釋放資源
scope.Dispose();
}
}
3、在TransactionScope中默認的事務級別是Serializable,即在事務過程中,完全性鎖表。別的進程不能查詢,修改,新增,刪除。這樣會導致效率大大降低,雖然數據完整性很高。通常我們不需要那么高的數據完整性。所以需要修改默認的事務級別:
所有的事務級別如下:
成員名稱 說明
Chaos 無法改寫隔離級別更高的事務中的掛起的更改。
ReadCommitted 不可以在事務期間讀取可變數據,但是可以修改它。
ReadUncommitted 可以在事務期間讀取和修改可變數據。
RepeatableRead 可以在事務期間讀取可變數據,但是不可以修改。可以在事務期間添加新數據。
Serializable 可以在事務期間讀取可變數據,但是不可以修改,也不可以添加任何新數據。
Snapshot 可以讀取可變數據。在事務修改數據之前,它驗證在它最初讀取數據之后另一個事務是否更改過這些數據。如果數據已被更新,則會引發錯誤。這樣使事務可獲取先前提交的數據值。
在嘗試提升以此隔離級別創建的事務時,將引發一個 InvalidOperationException,並產生錯誤信息“Transactions with IsolationLevel Snapshot cannot be promoted”(無法提升具有 IsolationLevel 快照的事務)。
Unspecified 正在使用與指定隔離級別不同的隔離級別,但是無法確定該級別。如果設置了此值,則會引發異常。
二、與數據庫事務結合
//創建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();
}
三、與WCF事務結合
