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

 

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

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

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

  1.  
    static void Main(string[] args)
  2.  
    {
  3.  
    using (TransactionScope ts = new TransactionScope())
  4.  
    {
  5.  
    userBLL u = new userBLL();
  6.  
    TeacherBLL t = new TeacherBLL();
  7.  
    u.ADD();
  8.  
    t.ADD();
  9.  
    ts.Complete();
  10.  
    }
  11.  
    }

只需要把需要事务包裹的逻辑块写在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

比如下面代码:

  1.  
    static void Main(string[] args)
  2.  
    {
  3.  
    using (TransactionScope ts = new TransactionScope())
  4.  
    {
  5.  
    Console.WriteLine(Transaction.Current.TransactionInformation.LocalIdentifier);
  6.  
    userBLL u = new userBLL();
  7.  
    TeacherBLL t = new TeacherBLL();
  8.  
    u.ADD();
  9.  
    using (TransactionScope ts2 = new TransactionScope(TransactionScopeOption.Required))
  10.  
    {
  11.  
    Console.WriteLine(Transaction.Current.TransactionInformation.LocalIdentifier);
  12.  
    t.ADD();
  13.  
    ts2.Complete();
  14.  
    }
  15.  
    ts.Complete();
  16.  
    }
  17.  
    }

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

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

  1.  
    static void Main(string[] args)
  2.  
    {
  3.  
    using (TransactionScope ts = new TransactionScope())
  4.  
    {
  5.  
    Console.WriteLine(Transaction.Current.TransactionInformation.LocalIdentifier);
  6.  
    userBLL u = new userBLL();
  7.  
    TeacherBLL t = new TeacherBLL();
  8.  
    u.ADD();
  9.  
    using (TransactionScope ts2 = new TransactionScope(TransactionScopeOption.RequiresNew))
  10.  
    {
  11.  
    Console.WriteLine(Transaction.Current.TransactionInformation.LocalIdentifier);
  12.  
    t.ADD();
  13.  
    ts2.Complete();
  14.  
    }
  15.  
    ts.Complete();
  16.  
    }
  17.  
    }

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

TransactionScopeOption的属性值:

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

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

C#中回滚TransactionScope的使用方法和原理的更多相关文章

  1. 【微信小程序项目实践总结】30分钟从陌生到熟悉 web app 、native app、hybrid app比较 30分钟ES6从陌生到熟悉 【原创】浅谈内存泄露 HTML5 五子棋 - JS/Canvas 游戏 meta 详解,html5 meta 标签日常设置 C#中回滚TransactionScope的使用方法和原理

    [微信小程序项目实践总结]30分钟从陌生到熟悉 前言 我们之前对小程序做了基本学习: 1. 微信小程序开发07-列表页面怎么做 2. 微信小程序开发06-一个业务页面的完成 3. 微信小程序开发05- ...

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

    TransactionScope只要一个操作失败,它会自动回滚,Complete表示事务完成 实事上,一个错误的理解就是Complete()方法是提交事务的,这是错误的,事实上,它的作用的表示本事务完 ...

  3. 浅析Mysql 数据回滚错误的解决方法

    介绍一下关于Mysql数据回滚错误的解决方法.需要的朋友可以过来参考下 MYSQL的事务处理主要有两种方法.1.用begin,rollback,commit来实现begin 开始一个事务rollbac ...

  4. 浅析Mysql数据回滚错误的解决方法

    介绍一下关于Mysql数据回滚错误的解决方法.需要的朋友可以过来参考下   MYSQL的事务处理主要有两种方法.   1.用begin,rollback,commit来实现   begin 开始一个事 ...

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

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

  6. 转:C#中TransactionScope的使用方法和原理

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

  7. 【网摘】C#中TransactionScope的使用方法和原理

    时间 2013-08-12 19:59:34  51CTO推荐博文 原文  http://cnn237111.blog.51cto.com/2359144/1271600 在.net 1.1的时代,还 ...

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

    出自51CTO博客:http://cnn237111.blog.51cto.com/2359144/1271600 在.net 1.1的时代,还没有TransactionScope类,因此很多关于事务 ...

  9. SQL Server:在事务中回滚TRUNCATE操作

    我们一般都认为TRUNCATE是一种不可回滚的操作,它会删除表中的所有数据以及重置Identity列. 如果你在事务中进行TRUNCATE操作,就能回滚.反之,它就不会从日志文件文件恢复数据.它不会在 ...

随机推荐

  1. vue2.0组件传值

    props down   emit up 嘿嘿    如果是第一次接触vue2.0组件传值的肯定很疑惑,这是什么意思(大神总结的,我也就是拿来用用) “down”—>指的是下的意思,即父组件向子 ...

  2. Linux 编译安装R语言

    一.安装依赖包 yum install -y gcc gcc-gfortran glibc-headers readline-devel libXt-devel gcc-c++ xz-devel.x8 ...

  3. BZOJ1925 [Sdoi2010]地精部落 动态规划

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1925 题意概括 给出n,n<=4200,问1~n这些数的排列中,有多少满足一下性质: 性质: ...

  4. linux SSH免密码登录远程服务器

    背景:无密码登录,所谓的无密码登录其实是指通过证书认证的方式登录,使用一种‘公私钥’认证的方式来进行ssh登录 在linux系统中,ssh是远程登录的默认工具,因为该工具的协议使用了RSA/DSA的加 ...

  5. Leaf:美团分布式ID生成服务开源

    Leaf是美团基础研发平台推出的一个分布式ID生成服务,名字取自德国哲学家.数学家莱布尼茨的一句话:“There are no two identical leaves in the world.”L ...

  6. 【Ray Tracing The Next Week 超详解】 光线追踪2-7 任意长方体 && 场景案例

    上一篇比较简单,很久才发是因为做了一些好玩的场景,后来发现这一章是专门写场景例子的,所以就安排到了这一篇 Preface 这一篇要介绍的内容有: 1. 自己做的光照例子 2. Cornell box画 ...

  7. <<c专家编程>>笔记

    C专家编程摘录 c操作符的优先级 有时一些c操作符有时并不会像你想象的那样工作. 下方表格将说明这个问题: 优先级问题 表达式 期望的情况 实际情况 . 优先级高于* *p.f (*p).f *(p. ...

  8. git使用经验for windows

    一.本地同步fork的最新版本 二.git命令 一.本地同步fork的最新版本 ①打开Git CMD工具,进入git的主目录 ②使用 git remote -v 查看fork的远程仓库地址 origi ...

  9. mysql 用户/密码/权限操作

    由于最近使用mysql遇到了修改用户密码的问题,所以一块学习了一下关于用户的相关操作: 1. 创建新账户 CREATE USER 'jeffrey'@'localhost'; 2. 账户设置密码 #当 ...

  10. Flask使用SQLAlchemy两种方式

    一.SQLAlchemy和Alembic 主要使用原生的SQLAlchemy进行数据库操作和使用Alemic进行数据库版本控制 I 创建数据库主要有三个步骤 创建表的父类/数据库连接/Session ...