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的主要内容,如果未能解决你的问题,请参考以下文章