`
expressren_2015
  • 浏览: 2015 次
社区版块
存档分类
最新评论

Spring Transaction属性之Propagation

 
阅读更多
引用
http://blog.csdn.net/kiwi_coder/article/details/20214939


Spring Transaction中有一个很重要的属性:Propagation。主要用来配置当前需要执行的方法,与当前是否有transaction之间的关系。

我晓得有点儿抽象,这也是为什么我想要写这篇博客的原因。看了后面的例子,大家应该就明白了。


一、Propagation取值:

REQUIRED(默认值):在有transaction状态下执行;如当前没有transaction,则创建新的transaction;

SUPPORTS:如当前有transaction,则在transaction状态下执行;如果当前没有transaction,在无transaction状态下执行;

MANDATORY:必须在有transaction状态下执行,如果当前没有transaction,则抛出异常IllegalTransactionStateException;

REQUIRES_NEW:创建新的transaction并执行;如果当前已有transaction,则将当前transaction挂起;

NOT_SUPPORTED:在无transaction状态下执行;如果当前已有transaction,则将当前transaction挂起;

NEVER:在无transaction状态下执行;如果当前已有transaction,则抛出异常IllegalTransactionStateException。


二、REQUIRED与REQUIRED_NEW

上面描述的6种propagation属性配置中,最难以理解,并且容易在transaction设计时出现问题的是REQUIRED和REQURED_NEW这两者的区别。当程序在某些情况下抛出异常时,如果对于这两者不够了解,就可能很难发现而且解决问题。


下面我们给出三个场景进行分析:

场景一:

ServiceA.java:

public class ServiceA {
    @Transactional
    public void callB() {
        serviceB.doSomething();
    }
}

ServiceB.java

public class ServiceB {
    @Transactional
    public void doSomething() {
        throw new RuntimeException("B throw exception");
    }
}
这种情况下,我们只需要在调用ServiceA.callB时捕获ServiceB中抛出的运行时异常,则transaction就会正常的rollback。


场景二

在保持场景一中ServiceB不变,在ServiceA中调用ServiceB的doSomething时去捕获这个异常,如下:

public class ServiceA {
    @Transactional
    public void callB() {
        try {
            serviceB.doSomething();
        } catch (RuntimeException e) {
            System.err.println(e.getMessage());
        }
    }
}
这个时候,我们再调用ServiceA的callB。程序会抛出org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only这样一个异常信息。原因是什么呢?

因为在ServiceA和ServiceB中的@Transactional propagation都采用的默认值:REQUREID。根据我们前面讲过的REQUIRED特性,当ServiceA调用ServiceB的时候,他们是处于同一个transaction中。如下图所示:


当ServiceB中抛出了一个异常以后,ServiceB会把当前的transaction标记为需要rollback。但是ServiceA中捕获了这个异常,并进行了处理,认为当前transaction应该正常commit。此时就出现了前后不一致,也就是因为这样,抛出了前面的UnexpectedRollbackException。


场景三

在保持场景二中ServiceA不变,修改ServiceB中方法的propagation配置为REQUIRES_NEW,如下:

public class ServiceB {
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void doSomething() {
        throw new RuntimeException("B throw exception");
    }
}
此时,程序可以正常的退出了,也没有抛出UnexpectedRollbackException。原因是因为当ServiceA调用ServiceB时,serviceB的doSomething是在一个新的transaction中执行的。如下图所示:


所以,当doSomething抛出异常以后,仅仅是把新创建的transaction rollback了,而不会影响到ServiceA的transaction。ServiceA就可以正常的进行commit。

当然这里把ServiceA和ServiceB放在两个独立的transaction是否成立,还需要再多多考虑你的业务需求。


Transaction不是一个新东西了,那对于transaction的使用会不会有一些模式?一些经验之谈呢?答案肯定是有的,以后博客再说。
分享到:
评论

相关推荐

    spring事物管理

    Spring在TransactionDefinition接口中规定了7种类型的事务传播行为,它们规定了事务方法和事务方法发生嵌套调用时事务如何进行传播 PROPAGATION_REQUIRED PROPAGATION_SUPPORTS PROPAGATION_MANDATORY PROPAGATION_...

    spring 事务传播

    系统理解spring事务传播属性,和隔离级别

    spring applicationContext 配置文件

    <bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean" p:dataSource-ref="dataSourceProxy"> <value>classpath:SqlMapConfig.xml</value> </property> ...

    spring-framework-reference-4.1.2

    3. New Features and Enhancements in Spring Framework 4.0 ............................................ 17 3.1. Improved Getting Started Experience .........................................................

    Spring + Hibernate + Struts 事务配置小例子(带提示框等小技巧)

    class="org.springframework.transaction.interceptor.TransactionInterceptor"> <!-- 事务拦截器bean需要依赖注入一个事务管理器 --> <!-- 下面定义事务传播属性 [ bus* 事务的方法名]--> *">...

    SPRING API 2.0.CHM

    Propagation PropertiesBeanDefinitionReader PropertiesEditor PropertiesFactoryBean PropertiesLoaderSupport PropertiesLoaderUtils PropertiesMethodNameResolver PropertiesPersister ...

    springmvc-ibatis

    <tx:advice id="txAdvice" transaction-manager="transactionManager"> *" read-only="true"/> *" propagation="REQUIRED"/> *" propagation="REQUIRED"/> *" propagation="REQUIRED"/> *" ...

    struts2.3+hibernate3.6+spring3.1整合的纯xml配置的小项目

    <tx:annotation-driven transaction-manager="txManager" /> <!-- <aop:config> expression="execution(* x.y.service.*Service.*(..))" /> id="noTxServiceOperation" expression="execution(* x.y....

    ssh(structs,spring,hibernate)框架中的上传下载

    第11~25行定义了Hibernate的会话工厂,会话工厂类用Spring提供的LocalSessionFactoryBean维护,它注入了数据源和资源映射文件,此外还通过一些键值对设置了Hibernate所需的属性。  其中第16行通过类路径的映射方式...

    spring-framework-reference4.1.4

    3. New Features and Enhancements in Spring Framework 4.0 ............................................ 17 3.1. Improved Getting Started Experience .........................................................

    SSH第7章上机.zip ACCP8.0

    org.springframework.transaction-3.1.3.RELEASE.jar 加入配置文件 加入spring的配置文件 加入hibernate的配置文件 加入配置代码 加入对SessionFactory的配置 加入数据源(DataSource)的配置 ...

    Myeclipse6.0中SSH框架搭建

    class="org.springframework.transaction.interceptor.TransactionInterceptor"> <property name="transactionManager" ref="transactionManager"></property> <property name="transactionAttributes"> ...

    springmvcmybatis

    <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context=...

    ssh框架在application.xml中配置数据源所需jar

    - Contains bean references to the transaction manager and to the DAOs in - dataAccessContext-local/jta.xml (see web.xml's "contextConfigLocation"). --> <beans xmlns="http://www.springframework.org/...

    SpringMVC+Hibernate全注解整合

    <tx:advice id="txAdvice" transaction-manager="transactionManager"> *" read-only="true" /> *" propagation="REQUIRED" /> *" propagation="REQUIRED" /> *" propagation="REQUIRED" /> *" ...

    SpringMVC-SSH全注解

    <tx:advice id="txAdvice" transaction-manager="transactionManager"> *" read-only="true" /> *" propagation="REQUIRED" /> *" propagation="REQUIRED" /> *" propagation="REQUIRED" /> *" ...

    客户关系管理系统框架搭建(二)

    @Transactional(isolation=Isolation.DEFAULT,propagation=Propagation.REQUIRED,readOnly=false) public void saveSysUserGroup(SysUserGroup sysUserGroup) { sysUserGroupDao.save(sysUserGroup)...

    三大框架下分页源代码

    <tx:advice id="txAdvice" transaction-manager="transactionManager"> *" propagation="REQUIRED"/> *" propagation="REQUIRED"/> *" propagation="REQUIRED"/> *" read-only="true"/> ...

Global site tag (gtag.js) - Google Analytics