分布式事物嵌套事物

1.内部事物 需 using (TransactionScope scope = new TransactionScope(TransactionScopeOption.RequiresNew))  否则会出现“已终止事物” 的错误

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

}

时间: 2024-11-05 16:03:27

分布式事物嵌套事物的相关文章

Spring事务管理--(二)嵌套事物详解

一.前言 最近开发程序的时候,出现数据库自增id跳数字情况,无奈之下dba遍查操作日志,没有delete记录.才开始慢慢来查询事物问题.多久以来欠下的账,今天该还给spring事物. 希望大家有所收获.2016年07月19日22:32:38 二.spring嵌套事物 1.展示项目代码--简单测springboot项目 整体项目就这么简单,为了方便.这里就只有biz层与service层,主要作为两层嵌套,大家只要看看大概就ok.后面会给出git项目地址,下载下来看一看就明白,力求最简单. 下面我们

逻辑是生物在进行思考的时候,用来在所思考的事物与事物之间进行联系的方法

我认为逻辑并无对错或有无之分,只有使用者的多少之分. 如果一定要定义,我会说:逻辑是生物在进行思考的时候,用来在所思考的事物与事物之间进行联系的方法.你可以用多种方法联系事物,没有哪一种是错的.只不过当别人和你所用的逻辑不同时,你们之间的交流会变得困难.你使用的逻辑与越多的人共用,你就越容易和这些人沟通以及获得认可.反之亦然.任何思维以及思维的衍生物都有逻辑,不同的只在于能被多少人所理解. 我们平时所说的"没逻辑",一般指的是"所使用的逻辑是错的".而这种感觉的成因

事物及事物隔离级别

什么是事物 事物是访问数据库的一个操作序列,数据库应用系统通过事物集来完成对数据库的存取.事物的正确执行使得数据库从一种状态转换为另一种状态. 事物必须服从ISO/IEC所制定的ACID原则.ACID是原子性(atomicity).一致性(consistency).隔离性(isolation).持久性(durability)的缩写,这四种状态的意思是: 1.原子性 即不可分割,事物要么全部被执行,要么全部不执行.如果事物的所有子事物全部提交成功,则所有的数据库操作被提交,数据库状态发生变化:如果

MySQL分布式事物(XA事物)的使用

有时一个系统的数据 放在不同的库之中.如果用普通的事物 一个分支库提交成功了,另外一个分支库提交失败了, 这候 两个库没有同步的成功或者失败.会导致系统数据的不完整. 对于处理这种情况 MySQL有了处理分布式(XA)事物的语法 XA START xid 用于启动一个带给定xid的XA事物. xid包含3个部分 gtrid,bqual,formatID gtrid 是一个分布式事物的标识符,一个分布式事物的每个XA事物的gtrid必须相同,这样可以明确知道每个XA事物属于哪个分布式事物. bqu

解惑spring嵌套事物

工作中一直对spring中的事物管理都是最简单的配置 但是spring中的事物传播性配置 还有很多种,有时候经常疑惑service调用service的问题,今天的论坛上看到一篇写的非常详细的文字.记录下来.猛击下面的链接地址 http://feiing.iteye.com/blog/35907 对于事物的其他知识请阅读这篇文章 http://my.oschina.net/huangyong/blog/160012

集成Spring事物管理

单独使用MyBatis对事物进行管理 前面MyBatis的文章有写过相关内容,这里继续写一个最简单的Demo,算是复习一下之前MyBatis的内容吧,先是建表,建立一个简单的Student表: create table student ( student_id int auto_increment, student_name varchar(20) not null, primary key(student_id) ) 建立实体类Student.java: public class Studen

MyBatis6:MyBatis集成Spring事物管理(下篇)

前言 前一篇文章<MyBatis5:MyBatis集成Spring事物管理(上篇)>复习了MyBatis的基本使用以及使用Spring管理MyBatis的事物的做法,本文的目的是在这个的基础上稍微做一点点的进阶:多数据的事物处理.文章内容主要包含两方面: 1.单表多数据的事物处理 2.多库/多表多数据的事物处理 这两种都是企业级开发中常见的需求,有一定的类似,在处理的方法与技巧上又各有不同,在进入文章前,先做一些准备工作,因为后面会用到多表的插入事物管理,前面的文章建立了一个Student相关

什么是事物?系统的详尽的认识事物------&gt;咬文嚼字版

文章目录: 事物的理解 壹.什么是事物?事物的 ACID(Atomicity .Consistency .Durability.Isolation )? 贰.脏读.不可重复读.幻读? 叁.事物的隔离级别? 深入理解 Spring 事务原理 壹.事务的基本原理 贰.Spring 事务的传播属性 叁.数据库隔离级别 肆.常量解释 伍.事务的嵌套 陆.总结 事物的认知 壹.什么是事物?事物的 ACID(Atomicity .Consistency .Durability.Isolation )? 事物

Spring中的事物管理,用 @Transactional 注解声明式地管理事务

事物: 事务管理是企业级应用程序开发中必不可少的技术,  用来确保数据的 完整性和 一致性. 事务就是一系列的动作, 它们被当做一个单独的工作单元. 这些动作要么全部完成, 要么全部不起作用 事务的四个关键属性: 原子性:事务是一个原子操作, 由一系列动作组成. 事务的原子性确保动作要么全部完成要么完全不起作用. 一致性:一旦所有事务动作完成, 事务就被提交. 数据和资源就处于一种满足业务规则的一致性状态中. 隔离性:可能有许多事务会同时处理相同的数据, 因此每个事物都应该与其他事务隔离开来,