天天看点

在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;
}