• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

C#分布式事务(TransactionScope)

原作者: [db:作者] 来自: [db:来源] 收藏 邀请
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();
  }
}

鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
还是C#好一些发布时间:2022-07-13
下一篇:
LinuxC语言检测文件是否存在发布时间:2022-07-13
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap