spring 注解 事务,声明事务共存 order 方案---有bug

Posted 汪小哥

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spring 注解 事务,声明事务共存 order 方案---有bug相关的知识,希望对你有一定的参考价值。

一、背景

spring 注解事务和声明事务共存下,出现一些奇怪的问题,声明事务不生效啦!本来对于业务异常不进行回滚,最终回滚啦,很是奇怪啊,调查了一下,进行了一些了解,最后才有这篇文章。

参考: https://blog.csdn.net/feng27156/article/details/8740223

二、配置

1、修改之前的配置

  <bean id="transactionManager"
          class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
        <property name="globalRollbackOnParticipationFailure" value="false"/>
    </bean>

    <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>

    <context:annotation-config/>
    <tx:advice id="defaultTxAdvice">
        <tx:attributes>
            <tx:method name="get*" propagation="SUPPORTS" read-only="true"/>
            <tx:method name="get*" propagation="SUPPORTS" read-only="true"/>
            <tx:method name="find*" propagation="SUPPORTS" read-only="true"/>
            <tx:method name="query*" propagation="SUPPORTS" read-only="true"/>
            <tx:method name="*" rollback-for="Exception"/>
        </tx:attributes>
    </tx:advice>

    <aop:config>
        <aop:pointcut id="ao_bo"
                      expression="(execution(* *..*ServiceImpl.*(..))"/>
        <aop:advisor pointcut-ref="ao_bo" advice-ref="defaultTxAdvice"/>
    </aop:config>

出现问题的使用:
某个Service上使用注解

抛出异常之后不进行回滚,但是测试回滚啦,恰恰就是优先级问题造成的问题。根据参考的文章进行了修改配置
将注解处理的优先级变为最高,然后就好啦!因为

2、修改之后的配置

增加了order的配置

 <bean id="transactionManager"
          class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
        <property name="globalRollbackOnParticipationFailure" value="false"/>
    </bean>

    <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" order="-2147483640"/>

    <context:annotation-config/>
    <tx:advice id="defaultTxAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="get*" propagation="SUPPORTS" read-only="true"/>
            <tx:method name="get*" propagation="SUPPORTS" read-only="true"/>
            <tx:method name="find*" propagation="SUPPORTS" read-only="true"/>
            <tx:method name="query*" propagation="SUPPORTS" read-only="true"/>
            <tx:method name="*" rollback-for="Exception"/>
        </tx:attributes>
    </tx:advice>

    <aop:config>
        <aop:pointcut id="ao_bo"
                      expression="execution(* *..*ServiceImpl.*(..))"/>
        <aop:advisor pointcut-ref="ao_bo" advice-ref="defaultTxAdvice" order="-2147483639"/>
    </aop:config>

问题

本文是小编在2019-05 的时候写的存稿,但是这个为什么有bug? 最近看了几篇博客深入了解了一些事务的相关源码,这里的坑真深!

一个简单的xml and 注解同时存在一个方法上PROPAGATION_NEW->PROPAGATION_NEW 会占用几个连接?? 答案两个,一个事务占用两个连接数 有点过分了。

PROPAGATION_REQUIRED -> PROPAGATION_NEW,方法抛了一个异常,导致了调用方法的入口事务 PROPAGATION_REQUIRED 造成了局部的异常 getConnectionHolder().setRollbackOnly(),入口事务 这里就会抛出异常 Transaction rolled back because it has been marked as rollback-only 导致回滚!即使调用者 A 捕获了这个异常也会回滚,当然可以通过参数设置 globalRollbackOnParticipationFailure 了解一下。

如何根本解决这个问题? 主要是解决 AOP 拦截的时候 将 XML 和 注解的 合二为一,有我没有你,有你没有我!这样的解决方案才理想,不然坑太多。

更多

系列文章一: spring 注解 事务,声明事务共存—有bug
系列文章二:spring 注解 事务,声明事务混用–解决问题
系列文章三:spring 事务采坑-xml注解 事务混用
系列文章四: spring 事务背后的故事
更多汪小哥

以上是关于spring 注解 事务,声明事务共存 order 方案---有bug的主要内容,如果未能解决你的问题,请参考以下文章

Spring 事务控制 -- 基于注解的声明式事务控制

spring 注解 事务,声明事务混用--解决问题

Springday03 AOPSpring声明式事务Spring编程式事务

Spring声明式事务注解@Transactional

java里声明式事务是啥意思呢?

Spring全注解开发---声明式事务模块