使用TransactionScopeOption 管理事务流

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

 1     void RootMethod()
 2     {
 3          using(TransactionScope scope = new TransactionScope())
 4          {
 5
 6               SomeMethod();
 7               scope.Complete();
 8          }
 9     }
10
11     void SomeMethod()
12     {
13          using(TransactionScope scope = new TransactionScope())
14          {
15
16               scope.Complete();
17          }
18     }

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

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

TransactionScope 对象有以下三个选项:

  • 联接环境事务,或者在环境事务不存在的情况下创建新的环境事务。
  • 成为新的根范围,也就是说,启动一个新事务并使该事务成为其自己范围中的新环境事务。
  • 根本不参与事务。因此没有环境事务。

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

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

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

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

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

Required



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


Requires New



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


Suppress



不参与任何事务


Required



参与环境事务


Requires New



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


Suppress



不参与任何事务

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

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

 1     using(TransactionScope scope1 = new TransactionScope())
 2     //Default is Required
 3     {
 4          using(TransactionScope scope2 = new
 5           TransactionScope(TransactionScopeOption.Required))
 6          {
 7          ...
 8          }
 9
10          using(TransactionScope scope3 = new TransactionScope(TransactionScopeOption.RequiresNew))
11          {
12          ...
13          }
14
15          using(TransactionScope scope4 = new
16             TransactionScope(TransactionScopeOption.Suppress))
17         {
18          ...
19         }
20     }

下面的示例演示一个不包含任何环境事务的代码块,它使用 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
    }
时间: 2024-10-27 13:37:50

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

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

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

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

1.问题 Java代码   Connection conn = DataSourceUtils.getConnection(); //开启事务 conn.setAutoCommit(false); try { Object retVal = callback.doInConnection(conn); conn.commit(); //提交事务 return retVal; }catch (Exception e) { conn.rollback();//回滚事务 throw e; }final

用ThreadLocal管理事务

1.适用场景 一个service,操作两个dao,要求两个dao为同一个事务,要么全成功,要么全失败. DBUtils,使用ThreadLocal 1 public class DbUtils { 2 //线程局部数据容器 3 private static ThreadLocal<Connection> tl = new ThreadLocal<Connection>(); 4 private static DataSource ds; 5 private static Conne

使用Spring注解方式管理事务与传播行为详解

使用Spring注解方式管理事务 前面讲解了怎么使用@Transactional注解声明PersonServiceBean底下所有的业务方法需要事务管理,那么事务是如何来管理的呢? 我们知道当每个业务方法执行的时候,它都会打开事务,在业务方法执行结束之后,它就会结束事务.那么它什么时候决定这个事务提交,什么时候决定这个事务回滚呢?原先我们手工控制事务的时候,通常这个事务的提交或回滚是由我们来操纵的,那现在我们采用容器的声明式事务管理,那我们如何知道事务什么时候提交,什么时候回滚呢?答案是:Spr

spring+springMVC中使用@Transcational方式管理事务的必须要配的东西。

spring中管理事务的配置方式除了@Transcational还有使用aop等,本文介绍@Transcational方式,但是推荐使用aop方式.因为如果有多个事务管理器的话,你在注解中还需要注明使用哪个事务管理器@Transactional("transactionManager1"). 一.spring中一定要记得加载所有需要的bean 如果使用注解方式的话一定要记得扫描注解,下边的例子表示扫描xxx.xxx下所有文件(包含每一级子文件夹)中除了@Controller以外的所有注

Spring整合JDBC以及AOP管理事务

本节内容: Spring整合JDBC Spring中的AOP管理事务 一.Spring整合JDBC Spring框架永远是一个容器,Spring整合JDBC其实就是Spring提供了一个对象,这个对象封装了JDBC技术,它可以操作数据库,这个对象可以放入Spring容器,交给Spring容器来管理.所以我们主要是要学习这个对象:JDBCTemplate.这个对象和DBUtils中的QueryRunner非常相似. 1. 导包 4+2+2(测试需要的包spring-test,新版本测试时还需要sp

Spring怎么管理事务?

我们一般通过aop管理事务,就是把代码看成一个纵向有序的,然后通过aop管理事务,就好比增删改的时候需要开启一个事务,我们给他配置一个required,required就是有事务就执行事务,没有就给他创建一个事务.查的时候不需要开启事务,就给他配置一个supports,supports就是说他有事务就执行事务,没有的话就不执行. 事务四特性: ACID ----->原子性(事务操作最基本单元,要么全部成功,要么全部失败) 一致性(指一个事务执行之前和执行之后数据库都必须处于一致性状态,事务成功,

spring 管理事务配置时,结果 报错: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here这个异常

java.lang.IllegalStateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here这个异常 这个错误,网上说的原因一大推,反正我这个出的问题 是因为 虽然我在 spring 里把事务都配置好了,结果运行就出现这个错误,看看配置都没什么问题,都是网上 案例 照 写编码的,还是错的,结果发现是因为 我

JavaEE中的事务管理——事务概述(1)

今天打算说一说事务管理,读者可能了解也有可能不了解,其实很简单(大牛请自行绕过).本来想引用个成语的啥的来描述事务的特点,但是搜肠刮肚也没有发现合适的,于是就找了下面几组成语来描述事务性.其实在官方文档中对于事务的描述也是分四个方面来说的.这里算是用自己的理解解释一下罢了. 第一对词语是:"开弓没有回头箭"和"前功尽弃"(功亏一篑?功败垂成?) 这一对词语结合起来看就是事务的原子性,就是我们平时说的要做就做完,要不做就一点儿也不要做.其中前面的做完就是说明这个事务已