【转载】C#中回滚TransactionScope的使用方法和原理

【转载】C#中回滚TransactionScope的使用方法和原理

TransactionScope只要一个操作失败,它会自动回滚,Complete表示事务完成

实事上,一个错误的理解就是Complete()方法是提交事务的,这是错误的,事实上,它的作用的表示本事务完成,它一般放在try{}的结尾处,不用判断前台操作是否成功,如果不成功,它会自己回滚。

在.net 1.1的时代,还没有TransactionScope类,因此很多关于事务的处理,都交给了SqlTransaction和SqlConnection,每个Transaction是基于每个Connection的。这种设计对于跨越多个程序集或者多个方法的事务行为来说,不是非常好,需要把事务和数据库连接作为参数传入。

在.net 2.0后,TransactionScope类的出现,大大的简化了事务的设计。示例代码如下:

static void Main(string[] args)
        {
            using (TransactionScope ts = new TransactionScope())
            {
                userBLL u = new userBLL();
                TeacherBLL t = new TeacherBLL();
                u.ADD();
                t.ADD();
                ts.Complete();
            }
        }

只需要把需要事务包裹的逻辑块写在using (TransactionScope ts = new TransactionScope())中就可以了。从这种写法可以看出,TransactionScope实现了IDispose接口。除非显示调用ts.Complete()方法。否则,系统不会自动提交这个事务。如果在代码运行退出这个block后,还未调用Complete(),那么事务自动回滚了。在这个事务块中,u.ADD()方法和t.ADD()方法内部都没有用到任何事务类。

TransactionScope是基于当前线程的,在当前线程中,调用Transaction.Current方法可以看到当前事务的信息。具体关于TransactionScope的使用方法,已经它的成员方法和属性,可以查看 MSDN

TransactionScope类是可以嵌套使用,如果要嵌套使用,需要在嵌套事务块中指定TransactionScopeOption参数。默认的这个参数为Required。

该参数的具体含义可以参考http://msdn.microsoft.com/zh-cn/library/system.transactions.transactionscopeoption(v=vs.80).aspx

比如下面代码:

static void Main(string[] args)
        {
            using (TransactionScope ts = new TransactionScope())
            {
                Console.WriteLine(Transaction.Current.TransactionInformation.LocalIdentifier);
                userBLL u = new userBLL();
                TeacherBLL t = new TeacherBLL();
                u.ADD();
                using (TransactionScope ts2 = new TransactionScope(TransactionScopeOption.Required))
                {
                    Console.WriteLine(Transaction.Current.TransactionInformation.LocalIdentifier);
                    t.ADD();
                    ts2.Complete();
                }
               ts.Complete();
            }
        }

当嵌套类的TransactionScope的TransactionScopeOption为Required的时候,则可以看到如下结果,他们的事务的ID都是同一个。并且,只有当2个TransactionScope都complete的时候才能算真正成功。

ED8FDA3E241D48B0A90F30A5AC8A9A59

如果把TransactionScopeOption设为RequiresNew,则嵌套的事务块和外层的事务块各自独立,互不影响。

static void Main(string[] args)
        {
            using (TransactionScope ts = new TransactionScope())
            {
                Console.WriteLine(Transaction.Current.TransactionInformation.LocalIdentifier);
                userBLL u = new userBLL();
                TeacherBLL t = new TeacherBLL();
                u.ADD();
                using (TransactionScope ts2 = new TransactionScope(TransactionScopeOption.RequiresNew))
                {
                    Console.WriteLine(Transaction.Current.TransactionInformation.LocalIdentifier);
                    t.ADD();
                    ts2.Complete();
                }
              ts.Complete();
            }
        }

22D29B0134CD4993B629F085EEBF63D9

可以看到,他们的事务id是不一样的。

TransactionScopeOption的属性值:

<span>【转载】C#中回滚TransactionScope的使用方法和原理</span>

对于多个不同服务器之间的数据库操作,TransactionScope依赖DTC(Distributed Transaction Coordinator)服务完成事务一致性。

但是对于单一服务器数据,TransactionScope的机制则比较复杂。主要用的的是线程静态特性。线程静态特性ThreadStaticAttribute让CLR知道,它标记的静态字段的存取是依赖当前线程,而独立于其他线程的。既然存储在线程静态字段中的数据只对存储该数据的同一线程中所运行的代码可见,那么,可使用此类字段将其他数据从一个方法传递到该第一个方法所调用的其他方法,而且完全不用担心其他线程会破坏它的工作。TransactionScope 会将当前的 Transaction 存储到线程静态字段中。当稍后实例化 SqlCommand 时(在此 TransactionScope 从线程局部存储中删除之前),该 SqlCommand 会检查线程静态字段以查找现有 Transaction,如果存在则列入该 Transaction 中。通过这种方式,TransactionScope 和 SqlCommand 能够协同工作,从而开发人员不必将 Transaction 显示传递给 SqlCommand 对象。实际上,TransactionScope 和 SqlCommand 所使用的机制非常复杂。

 

【转自】http://blog.csdn.net/wangxiaojia42121/article/details/53321625

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/119355.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 一文弄懂罗斯蒙特644温度变送器接线

    一文弄懂罗斯蒙特644温度变送器接线罗斯蒙特644温度变送器分为单输入644H和双输入644S两种,昌晖仪表在本文介绍温度变送器644接线,大家学习一起罗斯蒙特644温度变送器接线的注意事项。问题1:下图①位置这四个端子是干什么的?问题2:下图②位置这三个端子是干什么的?问题3:下图③位置这三个端子是干什么的?问题4:下图④位置这个插针是干什么的?问题5:下图⑤位置拨盘L和H位置代表什么?问题6:上图⑥位置这两个端子是干什么的?结…

    2022年6月21日
    76
  • 三角函数中的正弦、余弦、正切、余切、正割、余割函数性质及常用公式

    三角函数中的正弦、余弦、正切、余切、正割、余割函数性质及常用公式三角函数三角函数包括正弦 余弦 正切 余切 正割 余割函数 0 基础知识正弦 Sine sinA CB CA 余弦 Cosine cosA AB CA 正切 Tangent tanA CB BA 余切 Cotangent cotA 1 tanA BA CB 正割 Secant secA 1 cosA CA AB 余割 Cosecant cosecA 1 sinA CA CB1y sinx2y cosx

    2025年8月28日
    2
  • python加入中小学课程_浙江中小学信息技术科9月换新教材,课程新增Python、PPT、H5………

    python加入中小学课程_浙江中小学信息技术科9月换新教材,课程新增Python、PPT、H5………今年9月新学期,浙江省三到九年级的信息技术课将替换新教材。与老教材相比,新版教材更接地气,以后小学生就要学会做PPT、H5,开始接触算法、大数据等。据悉,这次教材的修订,是自2017年教育部发布高中信息技术新课标后,浙江省教研室组织省内教研员、骨干教师精心修撰的成果。近段时间,浙江省教研室组织小学和初中信息技术课老师,进行三到九年级新修订教材的培训。记者翻阅新教材大纲发现,从小学三年级一直到九…

    2022年5月16日
    55
  • phpsotrm 2021.4 激活破解方法

    phpsotrm 2021.4 激活破解方法,https://javaforall.net/100143.html。详细ieda激活码不妨到全栈程序员必看教程网一起来了解一下吧!

    2022年3月15日
    134
  • bytebuffer常用方法_bytebuffer.get

    bytebuffer常用方法_bytebuffer.getByteBuffer的心得

    2022年10月2日
    3
  • 此工作站和主域间的信任关系失败 又一解决办法_电脑加域后无管理员

    此工作站和主域间的信任关系失败 又一解决办法_电脑加域后无管理员某虚拟化的域控制器出现严重故障以至于不可修复,故使用之前Hyper-V中导出的备份恢复了域控制器。恢复后基本功能正常,但部分工作站登录时提示“此工作站和主域间的信任关系失败”。【解决方案】0、必须确保故障工作站没有其他的问题(如网络连接故障、DNS设置错误等);1、在不能登录域的工作站上,使用工作站本地的管理员用户登录系统;2、在工作站上打开powershell,输入Reset…

    2022年10月19日
    4

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号