TransactionScope

TransactionScope

      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;auto - 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),并尽可能快地完成和释放事务。在事务执行期间,您还应该避免执行任何不必要的、与数据库无关的代码,这能够防止资源被毫无疑义地锁定过长的时间。

<think>好的,用户想了解TransactionScope在.NET C#中的用法,特别是数据库事务处理。首先,我需要回忆TransactionScope的基本概念和它在分布式事务中的作用。TransactionScope提供了一种声明式的事务管理方式,简化了事务代码的编写。 接下来,用户可能需要知道如何正确使用TransactionScope,包括创建实例、作用域内的操作以及Complete方法的调用。需要注意,使用后必须调用Complete来提交事务,否则会自动回滚。另外,还要考虑不同数据库资源的登记,比如多个数据库连接的情况,这时需要启用分布式事务协调器(MSDTC),否则可能会抛出异常。 然后,异常处理是关键部分。在TransactionScope块中发生异常时,事务会自动回滚。用户需要了解如何捕获异常并处理,确保资源正确释放。同时,超时设置和隔离级别也是重要配置项,默认超时是1分钟,可以通过TransactionOptions调整。 可能的问题包括为什么事务没有提交,可能的原因是没有调用Complete方法,或者作用域未正确释放。此外,跨数据库的事务需要MSDTC服务,用户可能会遇到相关配置问题,需要指导如何启用和排查。 还要考虑到性能方面,长时间的事务或跨资源的事务可能会影响性能,建议合理设置超时和隔离级别。最后,提供示例代码能帮助用户更直观地理解用法,包括基本使用、嵌套作用域和异步支持。 用户可能还会关心TransactionScope的最佳实践,比如作用域应尽量小,及时释放资源,避免提升到分布式事务以提升性能。此外,兼容性问题,比如不同版本的.NET或数据库驱动对TransactionScope的支持情况,也需要提及。 总结起来,回答需要涵盖基本用法、异常处理、配置选项、常见问题及解决方案,并提供代码示例和最佳实践,确保用户能够正确使用TransactionScope处理数据库事务。</think>### TransactionScope 使用指南 (.NET C# 数据库事务处理) #### 一、基本概念 TransactionScope 是 .NET System.Transactions 命名空间下的类,用于简化分布式事务管理,支持单数据库连接或多个异构资源(如数据库+消息队列)的事务协调[^1]。 #### 二、基础用法 ```csharp using (var scope = new TransactionScope()) { try { using (var conn = new SqlConnection(connectionString)) { conn.Open(); // 执行数据库操作1 new SqlCommand("UPDATE Account SET Balance=100", conn).ExecuteNonQuery(); // 执行数据库操作2 new SqlCommand("INSERT INTO Log VALUES('操作记录')", conn).ExecuteNonQuery(); } scope.Complete(); // 必须显式提交 } catch (TransactionAbortedException ex) { Console.WriteLine("事务已回滚: " + ex.Message); } } ``` *关键点说明* 1. `scope.Complete()` 是提交事务的唯一方式,未调用时事务自动回滚 2. 嵌套作用域默认继承父事务,可通过 `TransactionScopeOption.RequiresNew` 创建新事务 3. 涉及多个数据库连接时,需要启用 MSDTC 服务 #### 三、配置参数 ```csharp var options = new TransactionOptions { IsolationLevel = IsolationLevel.ReadCommitted, // 默认隔离级别 Timeout = TimeSpan.FromSeconds(30) // 默认60秒 }; using (var scope = new TransactionScope(TransactionScopeOption.Required, options)) { // 事务操作 } ``` #### 四、常见问题解决方案 1. **事务未提交** - 检查是否遗漏 `scope.Complete()` - 确保未在作用域结束前释放连接 2. **分布式事务报错** ```csharp // 错误: Network access for Distributed Transaction Manager (MSDTC) has been disabled ``` - 解决方案:在Windows服务中启用MSDTC服务 - 服务器管理器 -> MSDTC属性 -> 勾选"允许网络DTC访问" 3. **异步操作支持** ```csharp using (var scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled)) { await AsyncDatabaseOperation(); scope.Complete(); } ``` #### 五、性能优化建议 1. 尽量使用 `TransactionScopeOption.Suppress` 避免不必要的事务提升 2. 设置合理的超时时间防止长时间锁 3. 避免在事务作用域内执行非数据库操作
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值