一、事務定義:
顯式事務:明確指定事務的開始,connection需要打開方可使用,默認為closed,即:顯示調用con.BeginTransaction()
隱式事務:無法明確指定事務的開始,默認connection已被打開為open
分布式隱式事務:使用TransactionScope類 , 【跨庫且使用同一個事務提交】
分布式顯式事務:使用CommittableTransaction類,con.EnlistTransaction(Transaction對象)//將連接登記到事務 【跨庫且使用同一個事務提交】
//以下事例采用Linq to SQL 數據源
二、顯示事務實例:
using (DataClasses1DataContext datacontext = new DataClasses1DataContext())
{
try
{
//必須打開連接,用於事務的創建
if (datacontext.Connection.State == ConnectionState.Closed) datacontext.Connection.Open();
//創建事務以及將創建的事務分配給該DataContext的Transaction
datacontext.Transaction = datacontext.Connection.BeginTransaction();
var test_tran = datacontext.Products.Where(a => a.ProductID < 5).OrderBy(a => a.ProductID).Select(a => a);
foreach (var test in test_tran)
{
test.ProductName = test.ProductName + "A";
}
//datacontext.SubmitChanges();
//提交事務
//datacontext.Transaction.Commit();
}
catch
{
//回滾事務
datacontext.Transaction.Rollback();
}
}
三、隱式事務實例:
using (MyDataContext datacontext = new MyDataContext())
TransactionOptions option=new TransactionOptions();
option.IsolationLevel =System.Transactions.IsolationLevel.ReadCommitted;//隔離級別
option.Timeout = new TimeSpan(0, 2, 0);//事務超時時間 為2分鍾 默認為60秒
using (TransactionScope scope = new TransactionScope()) {
try
{
//在無事務環境中執行操作,即:取消環境事務(TransactionScopeOption.Suppress)
//每次進入創建新的事務環境(TransactionScopeOption.RequiresNew)
//每次進入將檢測是否存在事務環境,若存在則使用,不存在則重新創建(TransactionScopeOption.Required)
var test_tran = datacontext.Products.Where(a => a.ProductID < 5).OrderBy(a => a.ProductID).Select(a => a);
foreach (var test in test_tran)
{
test.ProductName = test.ProductName + "A";
}
datacontext.SubmitChanges();
scope.Complete(); //代表完成事務,事務提交
}catch{//遇到異常自動回滾}
三、分布式隱式事務實例:
使用分布式事務必須開啟服務:Distributed Transaction Coordinator 否則報錯 “服務器 'MRWANG' 上的 MSDTC 不可用 ”
//分布在不同數據庫之間的事務操作,如下事例:MyDataContext 和 OtherDataContext 兩個不同數據庫 即:分布式
using (MyDataContext datacontext1 = new MyDataContext())
using (TransactionScope scope1 = new TransactionScope()) {
try{
var test = datacontext1.TestTable.Where(a => a.ID == 1);
foreach (var test in test)
{
test.Name = test.Name + "B";
}
datacontext1.SubmitChanges();
注:
///////////--如下設置以后,嵌套事務(scope2)提交將和外層(scope1)TransactionScope無關--////////////
//1.在無事務環境中執行操作,取消環境事務(TransactionScopeOption.Suppress)
//2.每次進入創建新的事務環境(TransactionScopeOption.RequiresNew)
///////////////--scope2提交將和外層(scope1)TransactionScope有密切關聯,scope2提交成功,外層遇到異常,則全部回滾,因為屬於同一個事務環境--//////////////
//1.每次進入將檢測是否存在事務環境,若存在則使用,不存在則重新創建(TransactionScopeOption.Required)
using (OtherDataContext datacontext2 = new OtherDataContext())
using (TransactionScope scope2=new TransactionScope(TransactionScopeOption.Required)) {
var test_tran = datacontext2.Products.Where(a => a.ProductID < 5).OrderBy(a => a.ProductID).Select(a => a);
foreach (var test in test_tran)
{
test.ProductName = test.ProductName + "A";
}
datacontext2.SubmitChanges();
scope2.Complete(); //只完成嵌套式的內部事務,但事務並未正式提交
} scope1.Complete(); //代表完成所有事務,事務正式提交
}catch{//遇到異常自動回滾}
三、分布式顯式事務實例:
using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["MySqlServer"].ConnectionString))
{
using (CommittableTransaction tran= new CommittableTransaction())
{
conn.Open();
conn.EnlistTransaction(tran);//將連接登記到事務
using (SqlCommand cmd = new SqlCommand())
{
cmd.Connection = conn;
cmd.CommandType = CommandType.Text;
try
{
cmd.CommandText = "insert into TranTable(Priority) values(1)";
cmd.ExecuteNonQuery();
cmd.CommandText = "insert into TranTable(Priority) values(256)";
cmd.ExecuteNonQuery();
tran.Commit();//提交事務
}
catch (SqlException ex)
{
//回滾
tran.Rollback();
}
}
}
conn.Close();
}
