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的时候才能算真正成功。

如果把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();}}

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

TransactionScopeOption的属性值:

对于多个不同服务器之间的数据库操作,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://www.cnblogs.com/bad-man/p/7923002.html

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

  1. mysql 回滚失败_浅析Mysql 数据回滚错误的解决方法

    MYSQL的事务处理主要有两种方法.1.用begin,rollback,commit来实现begin 开始一个事务 rollback 事务回滚 commit 事务确认 2.直接用set来改变mysql ...

  2. VMware12卸载之后安装其他版本导致回滚操作的解决方法之一

    第二篇博客,因为困扰了我很久,最后很神奇的解决了. 没有怎么记录,没有什么截图,先文字复述我当时的情况: 文字较多大家可以直接看下面的解决方法 1:运行VMware12时打开配置突然卡死,没有等待VM ...

  3. matlab作动态函数曲线图,[转载]Matlab中使用Plot函数动态画图方法总结

    本帖最后由 sonictl 于 2012-12-31 12:18 编辑 请删除我 清楚超靠靠靠 没办法,一会儿限制这不能发表,那不能发表的.... [转载]Matlab中使用Plot函数动态画图方法总 ...

  4. 查询oracle 数据库中回滚段中一个时间点被修改的表数据并还原表中原来数据

    利用下面的SQL就可以查处最近更改的数据. SQL> SELECT ID,NAME,VERSIONS_STARTTIME,VERSIONS_ENDTIME,VERSIONS_OPERATION ...

  5. windows驱动程序编写_如何在Windows中回滚驱动程序

    windows驱动程序编写 Updating a driver on your PC doesn't always work out well. Sometimes, they introduce b ...

  6. xp系统mtp驱动程序_在XP中回滚设备驱动程序

    xp系统mtp驱动程序 Sometimes in Windows XP when you update a device driver, the new driver version doesn't ...

  7. oracle一个循环中回滚继续,oracle回滚段

    http://hi.baidu.com/ipeipei/blog/item/34f84316f7126d4a20a4e950.html 1. 概述 本文主要从回滚段的原理,分配和使用,以及回滚段的相关 ...

  8. C#中TransactionScope的使用方法和原理

    在.net 1.1的时代,还没有TransactionScope类,因此很多关于事务的处理,都交给了SqlTransaction和SqlConnection,每个Transaction是基于每个Con ...

  9. GIt版本回滚的两种方法reset、revert

    在学习关于git版本回滚操作之前我们应该需熟练使用git log查看Git提交日志,同时也应学会使用git reflog查看Git提交日志. 可参考博客:git log的使用_WEB前端李志杰的博客- ...

最新文章

  1. java实验2词法分析程序设计
  2. 复制数据表的两种情况。
  3. 什么是VMware vSphere
  4. python template open_python and Template.
  5. Linux系统中退出vim的编辑器3种情况
  6. 关于J2EE+DOTNET的一些网站
  7. [html] HTML5如何播放ts视频流?
  8. 数字签名,数字证书,证书链原理
  9. java 旅行家的预算_洛谷 P1016 旅行家的预算 Java解法
  10. Swift中的数据存储
  11. 汇编观察a++和++a
  12. tomcat7下载安装
  13. 雅虎团队经验:网站页面性能优化的 34条
  14. 全面解析《嵌入式程序员应该知道的16个问题》
  15. Java——TCP/IP超详细总结
  16. 大数据可视化期末复习
  17. 适合年轻人的副业项目,想要赚钱养家就不要再懒了
  18. C语言建立循环单链表并输出
  19. 多可文档管理系统的手机版
  20. 14个10G电口模块(10GBase-T)的相关问题

热门文章

  1. 大数据_Flink_数据处理_命令行提交Job---Flink工作笔记0014
  2. 大数据之-Hadoop完全分布式_完全分布式模式下的集群配置---大数据之hadoop工作笔记0034
  3. ES10新特性_字符串扩展方法_trimStart--trimEnd---JavaScript_ECMAScript_ES6-ES11新特性工作笔记058
  4. Java的接口及实例(转)
  5. 根据sessionId获取Session对象
  6. opencv函数medianBlur( );
  7. mfc大观之三(创建对象)
  8. then 微信小程序_微信小程序和es6 promise的关系
  9. ajax/test1.txt,ajax原生请求方法.txt
  10. linux怎样卸载conda,【原创文章】生信软件环境conda的安装与卸载