`

Spring中的事务传播属性详解

    博客分类:
  • java
 
阅读更多

文章不错,转载于:http://developer.51cto.com/art/200812/102708.htm

 

 

在使用Spring时,大部分会用到他的声明式事务,简单的在配置文件中进行一些规则配置,利用Spring的AOP功能就能轻松搞定事务问题;这 里面就涉及到一个事务的传播属性问题Propagation,它在TransactionDefinition接口中定义,以供 PlatfromTransactionManager使用,PlatfromTransactionManager是spring事务管理的核心接口

TransactionDefinition 
public interface TransactionDefinition { 
 int getPropagationBehavior(); 
 int getIsolationLevel(); 
 int getTimeout(); 
 boolean isReadOnly(); 
} 

 

 

getTimeout()方法,它返回事务必须在多少秒内完成。

 

isReadOnly(),事务是否只读,事务管理器能够根据这个返回值进行优化,确保事务是只读的。

 

getIsolationLevel()方法返回事务的隔离级别,事务管理器根据它来控制另外一个事务可以看到本事务内的哪些数据。

 

在TransactionDefinition接口中定义了五个不同的事务隔离级别,ISOLATION_DEFAULT 这是一个PlatfromTransactionManager默认的隔离级别,使用数据库默认的事务隔离级别.另外四个与JDBC的隔离级别相对 应,ISOLATION_READ_UNCOMMITTED 这是事务最低的隔离级别,它充许别外一个事务可以看到这个事务未提交的数据。这种隔离级别会产生脏读,不可重复读和幻像读。

 

在TransactionDefinition接口中共有7种选项可用:

 

PROPAGATION_REQUIRED:支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。

 

PROPAGATION_SUPPORTS:支持当前事务,如果当前没有事务,就以非事务方式执行。

 

PROPAGATION_MANDATORY:支持当前事务,如果当前没有事务,就抛出异常。

 

PROPAGATION_REQUIRES_NEW:新建事务,如果当前存在事务,把当前事务挂起。

 

PROPAGATION_NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。

 

PROPAGATION_NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。

 

PROPAGATION_NESTED:支持当前事务,新增Savepoint点,与当前事务同步提交或回滚。

 

现在结合一个实例,应用以上各种传播属性来进行说明:首先声明两个bean:ServiceA和ServiceB,其中ServiceB被引

 ServiceA { 
         void methodA() { 
             ServiceB.methodB(); 
         } 
    } 
    ServiceB {
         void methodB() { 
         } 
    } 

 

 

 

接下来,我们就一一分析下:

 

PROPAGATION_REQUIRED

 

加入当前正要执行的事务不在另外一个事务里,那么就起一个新的事务;比如说,ServiceB.methodB的事务级别定义为 PROPAGATION_REQUIRED, 那么由于执行ServiceA.methodA的时候, ServiceA.methodA已经起了事务,这时调用ServiceB.methodB,ServiceB.methodB看到自己已经运行在 ServiceA.methodA 的事务内部,就不再起新的事务。而假如ServiceA.methodA运行的时候发现自己没有在事务中,他就会为自己分配一个事务。 这样,在ServiceA.methodA或者在ServiceB.methodB内的任何地方出现异常,事务都会被回滚。即使 ServiceB.methodB的事务已经被 提交,但是ServiceA.methodA在接下来fail要回滚,ServiceB.methodB也要回滚。

 

PROPAGATION_SUPPORTS

 

如果当前在事务中,即以事务的形式运行,如果当前不再一个事务中,那么就以非事务的形式运行。

 

PROPAGATION_MANDATORY

 

必须在一个事务中运行。也就是说,他只能被一个父事务调用。否则,他就要抛出异常。

 

PROPAGATION_REQUIRES_NEW

 

比如我们设计ServiceA.methodA的事务级别为PROPAGATION_REQUIRED,ServiceB.methodB的事务级 别为PROPAGATION_REQUIRES_NEW, 那么当执行到ServiceB.methodB的时候,ServiceA.methodA所在的事务就会挂起,ServiceB.methodB会起一个 新的事务,等待ServiceB.methodB的事务完成以后, 他才继续执行。他与PROPAGATION_REQUIRED 的事务区别在于事务的回滚程度了。因为ServiceB.methodB是新起一个事务,那么就是存在 两个不同的事务。如果ServiceB.methodB已经提交,那么ServiceA.methodA失败回滚,ServiceB.methodB是不 会回滚的。如果ServiceB.methodB失败回滚, 如果他抛出的异常被ServiceA.methodA捕获,ServiceA.methodA事务仍然可能提交。

 

PROPAGATION_NOT_SUPPORTED

 

当前不支持事务。比如ServiceA.methodA的事务级别是PROPAGATION_REQUIRED ,而ServiceB.methodB的事务级别是PROPAGATION_NOT_SUPPORTED, 那么当执行到ServiceB.methodB时,ServiceA.methodA的事务挂起,而他以非事务的状态运行完,再继续 ServiceA.methodA的事务。 网管联盟bitsCN_com

 

PROPAGATION_NEVER

 

不能在事务中运行。假设ServiceA.methodA的事务级别是PROPAGATION_REQUIRED, 而ServiceB.methodB的事务级别是PROPAGATION_NEVER, 那么ServiceB.methodB就要抛出异常了。

 

PROPAGATION_NESTED

 

理解Nested的关键是savepoint。他与PROPAGATION_REQUIRES_NEW的区别 是,PROPAGATION_REQUIRES_NEW另起一个事务,将会与他的父事务相互独立, 而Nested的事务和他的父事务是相依的,他的提交是要等和他的父事务一块提交的。也就是说,如果父事务最后回滚,他也要回滚的。 而Nested事务的好处也是他有一个savepoint

ServiceA { 
        void methodA() {             
       try { 
                ServiceB.methodB(); 
            } catch (Exception e) {  
                ServiceC.methodC(); 
            }  
        }  
    } 

 

 

 

也就是说ServiceB.methodB失败回滚,那么ServiceA.methodA会回滚到savepoint点 上,ServiceA.methodA可以选择另外一个分支,比如 ServiceC.methodC,继续执行,来尝试完成自己的事务;但是这个事务并没有在EJB标准中定义。

分享到:
评论

相关推荐

    Spring中事务的传播属性详解

    Spring中事务的传播属性详解,Spring中事务的传播属性详解

    Spring 事务隔离与事务传播的详解与对比

    Spring 事务隔离与事务传播的详解与对比 Spring是SSH中的管理员,负责管理其它框架,协调各个部分的工作。今天一起学习一下Spring的事务管理。Spring的事务管理分为声明式跟编程式。声明式就是在Spring的配置文件中...

    主题:详解spring事务属性.doc

    我们在使用Spring声明式事务时,有一个非常重要的概念就是事务属性。事务属性通常由事务的传播行为,事务的隔离级别,事务的超时值和事务只读标志组成。我们在进行事务划分时,需要进行事务定义,也就是配置事务的...

    Spring中的事务传播行为示例详解

    主要给大家介绍了关于Spring中事务传播行为的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用Spring具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧

    spring 事务详解

    spring的事务处理的详细说明和解析,事务的传播和使用的方式

    spring2.5学习PPT 传智博客

    使用Spring注解方式管理事务与传播行为详解 24.使用Spring配置文件实现事务管理 25.搭建和配置Spring与Hibernate整合的环境 26.Spring集成的Hibernate编码与测试 27.Struts与Spring集成方案1(Struts集成Spring) ...

    Spring中文帮助文档

    9.5.7. 事务传播 9.5.8. 通知事务操作 9.5.9. 结合AspectJ使用 @Transactional 9.6. 编程式事务管理 9.6.1. 使用TransactionTemplate 9.6.2. 使用PlatformTransactionManager 9.7. 选择编程式事务管理还是声明...

    spring.doc

    5.1.8.2Spring事务的传播属性 117 5.1.8.3Spring事务的隔离级别 117 拓展: 118 5.1.8.4以XML配置的 形式 119 拓展: 120 5.1.8.5以注解方式配置 125 拓展: 127 5.1.9使用CGLIB以XML形式配置事务 130 5.2 Spring+...

    spring事务Propagation及其实现原理详解

    主要介绍了spring事务Propagation及其实现原理详解,分享了相关代码示例,小编觉得还是挺不错的,具有一定借鉴价值,需要的朋友可以参考下

    Spring.3.x企业应用开发实战(完整版).part2

    10.3.1 Spring事务传播机制回顾 10.3.2 相互嵌套的服务方法 10.4 多线程的困惑 10.4.1 Spring通过单实例化Bean简化多线程问题 10.4.2 启动独立线程调用事务方法 10.5 联合军种作战的混乱 10.5.1 Spring事务管理器的...

    Spring API

    9.5.7. 事务传播 9.5.8. 通知事务操作 9.5.9. 结合AspectJ使用 @Transactional 9.6. 编程式事务管理 9.6.1. 使用TransactionTemplate 9.6.2. 使用PlatformTransactionManager 9.7. 选择编程式事务管理还是声明...

    Spring3.x企业应用开发实战(完整版) part1

    10.3.1 Spring事务传播机制回顾 10.3.2 相互嵌套的服务方法 10.4 多线程的困惑 10.4.1 Spring通过单实例化Bean简化多线程问题 10.4.2 启动独立线程调用事务方法 10.5 联合军种作战的混乱 10.5.1 Spring事务管理器的...

    java面试题,180多页,绝对良心制作,欢迎点评,涵盖各种知识点,排版优美,阅读舒心

    【Spring】Spring事务机制 93 声明式事物 93 编程式事务 94 【Spring】Spring声明式事务的五个特性 94 传播性 94 隔离级别 95 只读 96 事务超时 97 回滚规则 97 【Spring】SpringMVC请求处理流程 97 【Mybatis】...

Global site tag (gtag.js) - Google Analytics