zoukankan      html  css  js  c++  java
  • Spring 事务传播行为

    概述

    一般SSH的项目都是使用三层架构即Controller、Services、DAO。
    Spring 的事务一般都在Services定义,而Controller、DAO都不定义事务。
    那么 Services 方法调用 Services 的方法,事务是怎么执行的?
    有些人说不建议Service 调用Service,或者如果要Service 调用Service必须使用嵌套事务。真的是这样的吗?

    带着疑问继续了解Spring事务传播行为

    spring事务定义了7种传播行为,传播行为有什么作用?在什么情况下使用?

    Spring 事务传播行为

    Spring的TransactionDefinition类中定义了7中事务传播类型,代码如下:


     

    我们先来假设一个场景
    在 ServiceA 中方法 A() 调用 ServiceB 中方法 B()。
    Spring 的事务传播行为就是解决方法之间的事务传播的。
    基本方法调用场景如下:

    • 方法A有事务,方法B也有事务
    • 方法A有事务,方法B没有事务
    • 方法A没有事务,方法B有事务
    • 方法A没有事务,方法B也没有事务

    1. PROPAGATION_REQUIRED

    支持当前事务,如果当前没有事务,就新建一个事务。他也是Spring提供的默认事务传播行为,适合绝大数情况。

    如果A方法有事务,那么B方法就使用A方法的事务。
    如果A方法没有事务,那么B方法就创建一个新事物。

    2. PROPAGATION_SUPPORTS

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

    如果A方法有事务,那么B方法就使用A方法的事务。
    如果A方法没有事务,那么B方法就不使用事务的方式执行。

    3. PROPAGATION_MANDATORY

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

    如果A方法有事务,那么A方法就使用A方法事务。
    如果A方法没有事务,那么就抛出异常。

    该事务传播行为要求A方法必须以事务的方式运行

    4. PROPAGATION_REQUIRES_NEW

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

    如果A方法有事务,就把A方法的事务挂起,B方法新创建一个事务。
    如果A方法没有事务,那么B方法就创建一个新事务。

    5. PROPAGATION_NOT_SUPPORTED

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

    如果A方法有事务,那么就把A方法的事务挂起,B方法以非事务的方式执行。
    如果A方法没有事务,那么B也不使用事务执行。

    6. PROPAGATION_NEVER

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

    如果方法A有事务,那么就抛出异常。
    如果方法A没有事务,那么B方法就以非事务的方式运行。

    跟 3. PROPAGATION_MANDATORY 事务传播行为相反。

    7. PROPAGATION_NESTED

    如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则进行与PROPAGATION_REQUIRED类似的。

    如果A方法有事务,那么B方法就在A方法的事务中使用嵌套事务。
    如果A方法没有事务,那么方法B就新创建一个事务。

    嵌套事务

    嵌套事务是使用数据库的SavePoint(事务保存点)。需要底层数据库的支持。
    如果在Spring使用嵌套事务,需要满足一下3点。

    • 需要数据库支持。
      可以使用以下代码来判断数据库是否支持。
    Connection.getMetaData().supportsSavepoints();
    • JDK 1.4 才支持 java.sql.Savepoint 。所以JDK必须在1.4 及以上。

    • 还需要Spring中配置nestedTransactionAllowed=true。
      我们要设置 transactionManager 的 nestedTransactionAllowed 属性为 true, 注意, 此属性默认为 false!!!

     <bean id="transactionManager"  
            class="org.springframework.orm.hibernate4.HibernateTransactionManager">  
            <property name="sessionFactory" ref="sessionFactory" />  
            <property name="nestedTransactionAllowed">  
                <value>true</value>  
            </property>  
        </bean> 

    只读事务(Readonly Transaction)

    Spring 为了忽略那些不需要事务的方法,比如读取数据,这样可以有效的提高一些性能。

    事务超时 (Transaction Timeout)

    为了解决事务执行时间太长,消耗太多资源的问题,可以设置一个超时时间。如果该事务支持超过设置的时间,就回滚该事务。


    链接:https://www.jianshu.com/p/9637196d6b96



  • 相关阅读:
    Python方法
    Cpp求PI
    Asp.net身份验证和授权
    [转] 魔兽系列事件报道
    directxsdk aug 2006
    [转]转变的开始!NVIDIA更换新Logo
    wxWidgets 2.7.0 released
    OpenGL 和 Vista(续)
    暴雪员工的跳槽纪录
    3D版的星际争霸
  • 原文地址:https://www.cnblogs.com/zouhong/p/13287932.html
Copyright © 2011-2022 走看看