可通过调用一个方法来嵌套事务范围,该方法在使用其自己范围的方法中使用 TransactionScope,下面示例中的 RootMethod 方法就是前者这样的方法。

     void RootMethod()
{
using(TransactionScope scope = new TransactionScope())
{ SomeMethod();
scope.Complete();
}
} void SomeMethod()
{
using(TransactionScope scope = new TransactionScope())
{ scope.Complete();
}
}

最顶层事务范围称为根范围。

TransactionScope 类提供了多个重载构造函数,它们接受 TransactionScopeOption 类型的枚举,而该枚举定义范围的事务行为。

TransactionScope 对象有以下三个选项:

  • 联接环境事务,或者在环境事务不存在的情况下创建新的环境事务。

  • 成为新的根范围,也就是说,启动一个新事务并使该事务成为其自己范围中的新环境事务。

  • 根本不参与事务。因此没有环境事务。

如果用 Required 实例化范围并且存在环境事务,则该范围会联接该事务。相反,如果不存在环境事务,该范围就会创建新的事务并成为根范围。这是默认值。在使用Required 时,无论范围是根范围还是仅联接环境事务,该范围中的代码都不需要有不同的行为。该代码在这两种情况下的行为应相同。

如果用 RequiresNew 实例化范围,则它始终为根范围。它会启动一个新事务,并且其事务成为该范围中的新环境事务。

如果用 Suppress 实例化范围,则无论是否存在环境事务,范围都从不参与事务。用此值实例化的范围始终使其环境事务为 null

下表概括了上述这些选项。

 
TransactionScopeOption 是否存在环境事务 范围参与

Required

参与新事务(将成为根范围)

Requires New

参与新事务(将成为根范围)

Suppress

不参与任何事务

Required

参与环境事务

Requires New

参与新事务(将成为根范围)

Suppress

不参与任何事务

在 TransactionScope 对象联接现有环境事务时,除非范围中止该事务,否则释放范围对象的操作可能并不会结束事务。如果环境事务是由根范围创建的,则仅当释放根范围时,才会对事务调用 Commit。如果事务是手动创建的,则它将在中止或由其创建者提交时结束。

下面的示例演示一个 TransactionScope 对象,该对象创建了三个嵌套的范围对象,并用不同的 TransactionScopeOption 值对其中每个对象进行了实例化。

     using(TransactionScope scope1 = new TransactionScope())
//Default is Required
{
using(TransactionScope scope2 = new
TransactionScope(TransactionScopeOption.Required))
{
...
} using(TransactionScope scope3 = new TransactionScope(TransactionScopeOption.RequiresNew))
{
...
} using(TransactionScope scope4 = new
TransactionScope(TransactionScopeOption.Suppress))
{
...
}
}

下面的示例演示一个不包含任何环境事务的代码块,它使用 Required 创建了一个新范围 (scope1)。范围 scope1 是根范围,因为它创建了一个新事务(事务 A),并使事务 A 成为环境事务。Scope1 后来又创建了三个对象,并用不同的 TransactionScopeOption 值对其中每个对象进行了实例化。例如,scope2 是用 Required 创建的;由于存在环境事务,因此该范围联接 scope1 所创建的第一个事务。请注意,scope3 是新事务的根范围,而 scope4 则没有环境事务。

虽然 TransactionScopeOption 的默认值和最常用的值是 Required,但其他各值都有其独有的用途。

如果要保留代码段所执行的操作,并且不希望在操作失败的情况下中止环境事务,此时 Suppress 十分有用。例如,在要执行日志记录或审核操作时,或者在无论环境事务提交还是中止都要将事件发布给订户时。使用此值,可以在事务范围中包含非事务代码段,如下面的示例所示。

    using(TransactionScope scope1 = new TransactionScope())
{
try
{
//Start of non-transactional section
using(TransactionScope scope2 = new
TransactionScope(TransactionScopeOption.Suppress))
{
//Do non-transactional work here
}
//Restores ambient transaction here
}
catch
{}
//Rest of scope1
}

使用TransactionScopeOption 管理事务流的更多相关文章

  1. Entity Framework应用:使用Code First模式管理事务

    一.什么是事务 处理以数据为中心的应用时,另一个重要的话题是事务管理.ADO.NET为事务管理提供了一个非常干净和有效的API.因为EF运行在ADO.NET之上,所以EF可以使用ADO.NET的事务管 ...

  2. JDBC基础:JDBC快速入门,JDBC工具类,SQL注入攻击,JDBC管理事务

    JDBC基础 重难点梳理 一.JDBC快速入门 1.jdbc的概念 JDBC(Java DataBase Connectivity:java数据库连接)是一种用于执行SQL语句的Java API,可以 ...

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

    事物: 事务管理是企业级应用程序开发中必不可少的技术,  用来确保数据的 完整性和 一致性. 事务就是一系列的动作, 它们被当做一个单独的工作单元. 这些动作要么全部完成, 要么全部不起作用 事务的四 ...

  4. 用ThreadLocal管理事务

    1.适用场景 一个service,操作两个dao,要求两个dao为同一个事务,要么全成功,要么全失败.

  5. 通过案例掌握Spring 管理事务的步骤及配置

    案例描述  通过完成生成订单业务,掌握事务处理.  需要d_order表和d_item表  订单生成时的业务逻辑:向d_order插入1条数据的同时,向t_item中插入若干条数据  这就是一个独立的 ...

  6. spring是如何管理 事务的

    Spring提供的事务管理可以分为两类:编程式的和声明式的.编程式的,比较灵活,但是代码量大,存在重复的代码比较多:声明式的比编程式的更灵活方便.  1.传统使用JDBC的事务管理  以往使用JDBC ...

  7. 基于JDK动态代理和CGLIB动态代理的实现Spring注解管理事务(@Trasactional)到底有什么区别。

    基于JDK动态代理和CGLIB动态代理的实现Spring注解管理事务(@Trasactional)到底有什么区别. 我还是喜欢基于Schema风格的Spring事务管理,但也有很多人在用基于@Tras ...

  8. Spring -- <tx:annotation-driven>注解基于JDK动态代理和CGLIB动态代理的实现Spring注解管理事务(@Trasactional)的区别。

    借鉴:http://jinnianshilongnian.iteye.com/blog/1508018 基于JDK动态代理和CGLIB动态代理的实现Spring注解管理事务(@Trasactional ...

  9. 对Spring 容器管理事务支持的总结

    1.问题 Connection conn = DataSourceUtils.getConnection(); //开启事务 conn.setAutoCommit(false); try { Obje ...

随机推荐

  1. 循环队列+堆优化dijkstra最短路 BZOJ 4152: [AMPPZ2014]The Captain

    循环队列基础知识 1.循环队列需要几个参数来确定 循环队列需要2个参数,front和rear 2.循环队列各个参数的含义 (1)队列初始化时,front和rear值都为零: (2)当队列不为空时,fr ...

  2. 传统高斯模糊与优化算法(附完整C++代码)

    高斯模糊(英语:Gaussian Blur),也叫高斯平滑,是在Adobe Photoshop.GIMP以及Paint.NET等图像处理软件中广泛使用的处理效果,通常用它来减少图像噪声以及降低细节层次 ...

  3. TableLayout(表格布局)

    表格布局模型以行列的形式管理子控件,每一行为一个TableRow的对象,当然也可以是一个View的对象.TableRow可以添加子控件,每添加一个为一列. TableLayout属性: android ...

  4. 仙人掌(cactus)

    仙人掌(cactus) Time Limit:1000ms Memory Limit:64MB 题目描述 LYK 在冲刺清华集训(THUSC) !于是它开始研究仙人掌,它想来和你一起分享它最近研究的 ...

  5. java7-4 继承的练习

    1.Override和Overload的区别,Overload能改变返回值类型吗? 答: Override就是方法重写:在子类中,出现和父类中一模一样的方法声明的现象 Overload就是方法重载:在 ...

  6. [转] Linux下防火墙iptables用法规则详及其防火墙配置

    from: http://www.cnblogs.com/yi-meng/p/3213925.html 备注: 排版还不错,建议看以上的链接. iptables规则 规则--顾名思义就是规矩和原则,和 ...

  7. 在centos下部署docker内网私服

    Docker内网私服:docker-registry with nginx & ssl on centos docker-registry既然也是软件应用,自然最简单的方法就是使用官方提供的已 ...

  8. KindEditor

    1.官网 www.kindsoft.net 2.MVC下空置处理 例: 页面使用 @model XXModel....@Html.EditorFor(model => model.Content ...

  9. 类图和对象图教程-类(Class)、接口(Interface)、协作(collaboration)、依赖关系(Dependency)、泛化关系(Generalization)、关联关系(Association)以及实现关系(Realization)

    类图的概念 (转) 一.概述 类图(Class Diagram)是描述类.接口.协作以及它们之间关系的图,用来显示系统中各个类的静态结构.类图是定义其他图的基础,在类图基础上,可以使用状态图.协作图. ...

  10. 【MFC】序列化(Serialize)、反序列化(Deserialize)

    1.首先在头文件里面声明 DECLARE_SERIAL(CSelectionSerial) 2.重写CObject的Serialize函数 virtual void Serialize(CArchiv ...