事务异常手动回滚且方法正常返回

事务异常手动回滚且方法正常返回

背景

小X调事务接口A,接口通过@Transactional进行注解,接口A中调用数据库操作接口B
接口A对接口B调用操作进行try-catch-finally
接口B中有异常产生,会导致接口返回事务异常错误形式,影响外系统使用。

接口B异常需要回滚,但是为了外系统使用,接口A需要正常返回

解决方案

1.catch代码块中使用手动回滚
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();这样就无须接口A上的事务进行处理异常

DEMO验证列表

demo地址

  1. 测试只读事务只允许读取数据,不允许语句修改和插入
  2. 测试RuntimeException 回滚事务与否
  3. 测试RuntimeException 手动回滚事务+正常返回
  4. 测试非RuntimeException 回滚事务与否
  5. 测试非RuntimeException catch异常,正常返回,不回滚事务
  6. 测试非RuntimeException throw RuntimeException异常,回滚事务
  7. 测试同一个类中 非事务方法调用事务方法
  8. 测试不同类中 非事务方法调用事务方法
  9. 测试不同类中 事务方法嵌套调用事务方法,requirednew 嵌套事务异常 外层事务同时会回滚
  10. 测试不同类中 事务方法嵌套调用事务方法,requirednew 外层事务异常 外层事务同时会回滚,嵌套事务不会回滚

扩展

只读事务和非只读事务的区别

只读事务:1.一个接口中如果执行多条报表查询,为了确保数据一致性,是需要给该接口增加只读事务的; 2.只读事务中不能进行语句的插入或者修改操作 3.只读事务异常,不会进行事务回滚
非只读事务:1.能进行语句修改和插入;2.会进行事务回滚

同一个类中非事务方法调用事务方法,因为类会产生代理类,代理类调用target类的非事务方法,导致实际调用执行为target中的事务方法(没有进行AOP代理)

spring xml事务配置

<!-- from the file 'context.xml' -->  
<?xml version="1.0" encoding="UTF-8"?>  
<beans xmlns="http://www.springframework.org/schema/beans"  
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
     xmlns:aop="http://www.springframework.org/schema/aop"  
     xmlns:tx="http://www.springframework.org/schema/tx"  
     xsi:schemaLocation="  
     http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd  
     http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd  
     http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">  
    
  <!-- 首先我们要把服务对象fooService声明成一个bean -->  
  <bean id="fooService" class="x.y.service.DefaultFooService"/>  
  
  <!-- 然后是声明一个事物建议tx:advice,spring为我们提供了事物的封装,这个就是封装在了<tx:advice/>中 -->
  <!-- <tx:advice/>有一个transaction-manager属性,我们可以用它来指定我们的事物由谁来管理。 -->
  <tx:advice id="txAdvice" transaction-manager="txManager">  
  <!-- 配置这个事务建议的属性 -->  
  <tx:attributes>  
    <!-- 指定所有get开头的方法执行在只读事务上下文中 -->  
    <tx:method name="get*" read-only="true"/>  
    <!-- 其余方法执行在默认的读写上下文中 -->  
    <tx:method name="*"/>  
  </tx:attributes>  
  </tx:advice>  
    
  <!-- 我们定义一个切面,它匹配FooService接口定义的所有操作 -->  
  <aop:config>  
	<!-- <aop:pointcut/>元素定义AspectJ的切面表示法,这里是表示x.y.service.FooService包下的任意方法。 -->
  <aop:pointcut id="fooServiceOperation" expression="execution(* x.y.service.FooService.*(..))"/>  
	<!-- 然后我们用一个通知器:<aop:advisor/>把这个切面和tx:advice绑定在一起,表示当这个切面:fooServiceOperation执行时tx:advice定义的通知逻辑将被执行 -->
  <aop:advisor advice-ref="txAdvice" pointcut-ref="fooServiceOperation"/>  
  </aop:config>  
    
  <!-- 数据元信息 -->  
  <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">  
  <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>  
  <property name="url" value="jdbc:oracle:thin:@rj-t42:1521:elvis"/>  
  <property name="username" value="scott"/>  
  <property name="password" value="tiger"/>  
  </bean>  
  
  <!-- 管理事务的类-->  
  <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">  
  <property name="dataSource" ref="dataSource"/>  
  </bean>   
  <!-- other <bean/> definitions here -->  
</beans>  

引用

RuntimeException和Exception的区别 https://www.cnblogs.com/jtlgb/p/5985120.html
https://zhuanlan.zhihu.com/p/38208248
https://zhuanlan.zhihu.com/p/56070261
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值