TransactionScope 分布式事务的使用案例 以及简单说明

 TransactionScope 是的.net Framework2.0版本中增加的一个新命名空间。他的用途是为数据库访问提供一个“轻量级”的事物。使用之前必须添加对 System.Transactions.dll 的引用。先介绍介绍几个简单的参数。

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 分钟)。
TransactionOptions opt= new TransactionOptions();
//设置TransactionOptions

opt.IsolationLevel = IsolationLevel.ReadCommitted;
// 设置超时间隔为2分钟,默认为60秒
opt.Timeout = new TimeSpan(0, 2, 0);

使用时候将

using (TransactionScope sCope = new TransactionScope(TransactionScopeOption.RequiresNew, opt))

其他和默认一样

下面做一个简单的demo 只需要添加很少的几行代码,这个模型可以对异常进行处理,执行结束后会自行清理,此外,它还可以对命令的提交或回滚进行管理

1.TransactionScope  在一个事务范围内

在app.config中

 

<connectionStrings>
    <add name="myCon" connectionString="Data Source=.;uid=sa;pwd=sa;database=B2C3;Asynchronous Processing=true"/>
    <add name="myCon2" connectionString="Data Source=.;uid=sa;pwd=sa;database=b2c;Asynchronous Processing=true"/>
    <add name="myCon3" connectionString="Data Source=.;uid=sa;pwd=sa;database=demo;Asynchronous Processing=true"/>
    <add name="myCon4" connectionString="Data Source=.;uid=sa;pwd=sa;database=News;Asynchronous Processing=true"/>


  </connectionStrings>

 

 

 static void Main(string[] args)
        {
           string constr = ConfigurationManager.ConnectionStrings["myCon"].ConnectionString;
            string constr2 = ConfigurationManager.ConnectionStrings["myCon2"].ConnectionString;
            string sql = "insert into [Tuser](username,pwd,age) values('新闻socpe测试','bbb',10)";
            #region 不同库的事务
            using (TransactionScope sope = new TransactionScope())
            {

                 using(SqlConnection con =new SqlConnection(constr))
                {
                    using (SqlCommand cmd = new SqlCommand(sql, con))
                    {
                        con.Open();
                      int a=  cmd.ExecuteNonQuery();
                      Console.WriteLine(a);
                   
                    }
                  
               
                }
                using (SqlConnection con = new SqlConnection(constr2))
                {
                    using (SqlCommand cmd = new SqlCommand(sql, con))
                    {
                        con.Open();
                        int b = cmd.ExecuteNonQuery();
                        Console.WriteLine(b);

                    }


                }

                addOtherUser();
                sope.Complete();

 

            }
            #endregion

    sope.Complete(); 是个标示。只有全部运行才提交事务

2.嵌套 调用事务

 

        static void Main(string[] args)
        {


            string constr = ConfigurationManager.ConnectionStrings["myCon"].ConnectionString;
            string constr2 = ConfigurationManager.ConnectionStrings["myCon2"].ConnectionString;
            string sql = "insert into [Tuser](username,pwd,age) values('新闻socpe测试','bbb',10)";
            #region 不同库的事务
            using (TransactionScope sope = new TransactionScope(TransactionScopeOption.Required))
            {

            
                using(SqlConnection con =new SqlConnection(constr))
                {
                    using (SqlCommand cmd = new SqlCommand(sql, con))
                    {
                        con.Open();
                      int a=  cmd.ExecuteNonQuery();
                      Console.WriteLine(a);
                   
                    }
                  
               
                }
                using (SqlConnection con = new SqlConnection(constr2))
                {
                    using (SqlCommand cmd = new SqlCommand(sql, con))
                    {
                        con.Open();
                        int b = cmd.ExecuteNonQuery();
                        Console.WriteLine(b);

                    }


                }

                addOtherUser();
                sope.Complete();

 

            }
            #endregion

 

 

 


        }

        private static void addOtherUser()
        {
            string constr3 = ConfigurationManager.ConnectionStrings["myCon3"].ConnectionString;
            string constr4 = ConfigurationManager.ConnectionStrings["myCon4"].ConnectionString;
            string sql1 = "insert into [hr_user](username,password) values('新闻socpe测试','bbb')";
            string sql2 = "insert into [Users](username,userpwd) values('新闻socpe测试','bbb')";

            //RequiresNew 这个事务范围将创建自己的事务。
            using(TransactionScope sope=new TransactionScope(TransactionScopeOption.RequiresNew))
            {

                using (SqlConnection con = new SqlConnection(constr3))
                {
                    using (SqlCommand cmd = new SqlCommand(sql1, con))
                    {
                        con.Open();
                        int a = cmd.ExecuteNonQuery();
                        Console.WriteLine(a);

                    }


                }
                using (SqlConnection con = new SqlConnection(constr4))
                {
                    using (SqlCommand cmd = new SqlCommand(sql2, con))
                    {
                        con.Open();
                        int b = cmd.ExecuteNonQuery();
                        Console.WriteLine(b);

                    }


                }
                sope.Complete();
            }
       
        }

 

 总结:

现在知道了TransactionScope中的数据库操作实际是参与了其中的环境事务,将它理解为是自动建立的SqlTransaction,而嵌套在其中的TransactionScope中的数据库操作会添加到这个环境事务中(以TransactionScopeOption.Required为参数生成的TransactionScope)。

  也知道了Complete方法并不是执行后,就会提交事务,而只是表明之前的动作都符合要求,只是一种确认,不执行该方法,事务便不能完成。而只有最外层TransactionScope执行了Complete方法后,在离开using块时,事务才真正的提交。所以说TransactionScope是能嵌套的。

  Transaction类有一静态属性Current,在一个TransactionScope中的Complete方法执行之前可以访问,它返回的便是环境事务。

但是:   进入和退出事务都要快,这一点非常重要,因为事务会锁定宝贵的资源。最佳实践要求我们在需要使用事务之前再去创建它,在需要对其执行命令前迅速打开连接,执行动作查询 (Action Query),并尽可能快地完成和释放事务。在事务执行期间,您还应该避免执行任何不必要的、与数据库无关的代码,这能够防止资源被毫无疑义地锁定过长的时间

 

 


        }

 

 

 

 

转载于:https://www.cnblogs.com/zhbsh/archive/2011/05/14/2046042.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值