首页 > 代码库 > spring 注解 事务,声明事务共存的情况下,先后顺序

spring 注解 事务,声明事务共存的情况下,先后顺序

最近在项目中,因为已配置全局声明式事务.不知道是否本来就配得有问题,导致一个多线程插入的方法会因为连接池不够用而导致失败.

就打算试试用注解式事务,然后发现不起作用,就想是不是嵌套事务的问题.然后找到这个哥们的文章,就解决了问题.这里转载一份

转载:http://blog.csdn.net/jeep_ouc/article/details/43056977

 

 

COME FROM

首先先看配置文件:

 

 
<!-- hibernate -->  
    <bean id="sessionFactory"  
        class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">  
        <property name="dataSource" ref="dataSource" />  
        <property name="hibernateProperties">  
            <props>  
                <prop key="hibernate.hbm2ddl.auto">update</prop>  
                <prop key="hibernate.show_sql">true</prop>  
                <prop key="hibernate.format_sql">true</prop>  
                <prop key="connection.autoReconnect">true</prop>  
                <prop key="connection.autoReconnectForPools">true</prop>  
                <prop key="connection.is-connection-validation-required">true</prop>  
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>  
            </props>  
        </property>  
        <property name="mappingDirectoryLocations">  
            <list>  
                <value>classpath*:*oddtech/bean</value>  
            </list>  
        </property>  
    </bean>  
  
    <!-- 事務管理 -->  
    <bean id="txManager"  
        class="org.springframework.orm.hibernate3.HibernateTransactionManager">  
        <property name="sessionFactory" ref="sessionFactory" />  
    </bean>  
    <!-- 註解式事務的支持 -->  
    <tx:annotation-driven transaction-manager="txManager"  order="0"/>  
    <!-- 服務事務註冊切面 -->  
    <aop:config >  
        <aop:pointcut expression="execution(* oddtech.service.impl.*.*(..))"  
            id="txPoint"  />  
        <aop:advisor advice-ref="txAdvice" pointcut-ref="txPoint"  order="1"/>  
    </aop:config>  
  
      
  
  
    <tx:advice transaction-manager="txManager" id="txAdvice">  
        <tx:attributes >  
            <tx:method name="find*" propagation="REQUIRED" read-only="true"   
                rollback-for="Exception" />  
            <tx:method name="select*" propagation="REQUIRED" read-only="true"  
                rollback-for="Exception" />  
            <tx:method name="insert*" propagation="REQUIRED"    
                rollback-for="Exception" />  
            <tx:method name="delete*" propagation="REQUIRED"  
                rollback-for="Exception" />  
            <tx:method name="update*" propagation="REQUIRED"   
                rollback-for="Exception" />  
            <tx:method name="modify*" propagation="REQUIRED"  
                rollback-for="Exception" />  
            <tx:method name="*" read-only="true"  
                rollback-for="Exception" />  
        </tx:attributes>  
    </tx:advice>  

 

 

当在oddtech.service.impl包下某个类(Test)某个方法(insert)使用了@Transactional,相当于在执行new Test().insert() 方法执行2次AOP切面。那么我们需要通过order 属性去定义AOP切面的先后执行顺序。 order越小,在AOP的chain 中越靠前,越先执行。(chain模式)

技术分享

所以 我们需要在<tx:annotation-driven transaction-manager="txManager"  order="0"/>中加入order属性为0,<aop:advisor advice-ref="txAdvice" pointcut-ref="txPoint"  order="1"/>加入order 属性为1.那么他们两个的执行顺序如下:技术分享

。这样就属于事务嵌套。

那么我们再看上边说的例子:当在oddtech.service.impl包下某个类(Test)某个方法(insert)使用了@Transactional,那么我们想让insert 方法只读,read-only=true,那么我们需要这样去定义:@Transactional(readOnly = true,propagation=Propagation.REQUIRED),为什么呢?

在声明事务中,我们对insert 的事务传播级别定义为:REQUIRED,关于事务传播级别,请参照http://blog.csdn.net/feng27156/article/details/8534609,那么在注解事务中我们定义REQUIRED 的事务。声明事务在使用注解定义的事务级别。

除非在特殊的情况下,注解事务不要和声明事务有冲突。声明事务定义的是统一的规则,如果你想让某一个方法有特殊的事务传播机制的话,那么不要和统一的规则有冲突。

<tx:method name="*" read-only="true" rollback-for="Exception" />

按照規則,定義一個test方法,加入:@Transactional定義。则test 方法爲read-only=false,propagation=REQUIRED。這是默認的。統一規則<tx:method name="*" read-only="true" rollback-for="Exception" />不會對test方法的註解事務衝突。

 

spring 注解 事务,声明事务共存的情况下,先后顺序