天天看點

在ADO.NET中實作事務

1. ADO.NET事務的主要成員

 需要使用事務管理的情況很多,在資料層使用得特别廣泛,幾乎每一個系統的資料層都會實作事務。資料層的事務都是繼承自DBTransaction,派生自IDbTransaction的。下面介紹一下IDbTransaction的基本成員:

public interface IDbTransaction:IDisposable
{
      IDbConnection Connection {get;}     //傳回Connection對象
      IsolationLevel IsolationLevel{get;}   
void Commit();      //資料送出,把所有改變資料儲存到持久化資料庫
      void Rollback();     //資料復原,把所有資料恢複原值
}      

  其中Connection屬性是傳回初始化此事務時所引用的連接配接對象的。Commit()方法應該在完成所有資料操作後才調用,調用該方法後,已經改變的資料将會儲存到持久化資料庫當中。而Rollback()是出現錯誤時調用的,調用後資料将傳回初始值。IsolationLevel是指定遇到其它并行事務時的處理方式。

  ADO.NET當中有多個子類都繼續自DBTransaction,其中SqlTransaction是比較常用的,SqlTransaction中還定義了一個Save()方法,這個方法允許開發人員把失敗的事務復原到上一個儲存點而不復原整個事務。而在DataContext類裡面,Transaction屬性會傳回DBTransaction對象。

在ADO.NET中實作事務

2. 開發執行個體

  在傳統的ADO.NET中使用事務,方法如下:.

private static void Execute(string connectionString)
{
using (SqlConnection connection = new SqlConnection(connectionString))
    {
        connection.Open();

        SqlCommand command = connection.CreateCommand();
        SqlTransaction transaction;

//啟動事務
        transaction = connection.BeginTransaction("SampleTransaction");

//設定SqlCommand的事務和連接配接對象
        command.Connection = connection;
        command.Transaction = transaction;

try
        {
            command.CommandText ="Insert into ......";
            command.ExecuteNonQuery();

// 完成送出
            transaction.Commit();
            ......
        }
catch (Exception ex)
        {
//資料復原
            transaction.Rollback();
            .....
        }
    }
}      

  在DataContext中使用事務,方法極其相似,不同的是SqlCommand中事務為SqlTransaction,在DataContext中事務為DbTransaction

using(MyDataContext context=new MyDataContext())
{
try
      {
          context.Connection.Open();
          context.Transaction=context.Connection.BeginTransaction();
//更新資料
          .........
          context.SubmitChanges();
//事務送出
          context.Transaction.Commit();
      }
catch(Excetion ex)
      {
//資料復原
         context.Transaction.Rollback();
//錯誤處理
         .........
      }
}      

四、隐式事務 TransactionScope

  1. TransactionScope的概念

  TransactionScope存在于System.Transactions 命名空間中, 它是從Framework 2.0開始引入的一個事務管理類,它也是微軟推薦使用的一個事務管理類。在TransactionScope的構造函數中會自動建立了一個新的LTM(輕量級事務管理器),并通過Transaction.Current 隐式把它設定為環境事務。在使用隐式事務時,事務完成前程式應該調用TransactionScope的Complete()方法,把事務送出,最後利用Dispose()釋放事務對象。若執行期間出現錯誤,事務将自動復原。

public class TransactionScope:IDisposable
{
//多個構造函數
    public TransactionScope();
public TransactionScope(Transaction)
public TransactionScope(TransactionScopeOption)
    ......
public void Complete();   //送出事務
    public void Dispose();     //釋放事務對象
}

//調用方式
using(TransactionScope scope=new TransactionScope())
{
//執行事務型工作
     ............
     scope.Complete();
}      

2. TransactionScope的構造函數 TransactionScope(transactionScopeOption)

 TransactionScopeOption 是枚舉的一個執行個體,它主要用于TransactionScope的構造函數内,定義事務生成的狀态要求。

成員名稱 說明
Required 該範圍需要一個事務。 如果已經存在環境事務,則使用該環境事務。 否則,在進入範圍之前建立新的事務。 這是預設值。
RequiresNew 總是為該範圍建立新事務。
Suppress 環境事務上下文在建立範圍時被取消。 範圍中的所有操作都在無環境事務上下文的情況下完成。

 這裡Suppress有點特别,當使用Suppress範圍内,所有的操作都将在無事務的上下文中執行,即當中的程式不再受到事務的保護,這大多數在嵌套式事務中使用。

void DoWork()
{
using(TransactionScope scope=new TransactionScope())
    {
//在事務環境中執行操作
         ......  
         NoTransaction();
         scope.Complete();
    }
}

void NoTransaction()
{
//在無事務環境中執行操作
    using(TransactionScope scope=new TransactionScope(TransactionScopeOption.Suppress))
    {
        ......
    }
}      

3. 應用執行個體,在Entity Framework中使用TransactionScope

public Order GetOrder(int id)
{
    BusinessContext _context = new BusinessContext();
    Order order = null;
try
    {
using (TransactionScope scope = new TransactionScope())
        { 
//資料操作
            var list = _context.Order.Include("OrderItem")
                .Where(x => x.ID == id);
if (list.Count() > 0)
                order = list.First();
else
                order = new Order();
            scope.Complete();      //事務送出
        }
    }
catch (Exception ex)
    {
        ...... //出錯處理,并傳回一個空對象
        order=new Order();   
    }
    _context.Dispose();
return order;
}