spring的嵌套事务问题

20 篇文章 0 订阅
9 篇文章 1 订阅

目录

线上问题:

事务注意事项

总结:


线上问题:

仔细分析了抛出的异常,发现异常为SocketTimeoutException,查阅事务回滚时需要的异常,发现

默认事务只对error和runtimeException异常会进行回滚,其他异常不会回滚,https://www.cnblogs.com/tianyuchen/p/6678084.html

加上@Transactional(rollbackFor=MyException.class)后事务会捕捉到此类异常,

在Spring里,同样只会rollback unchecked exception(RuntimeExcption及子类),而checked exception(Exception及子类)是不会rollback的,除非你特别声明。

 @Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW,rollbackFor = {MyException1.class,MyException2.class})    

因此所有在service层方法中用throws定义的Exception,都必须在事务定义中进行rollback设定。(请勿善忘)

所有在service层方法中被catch处理了的异常,又希望容器辅助rollback的话,必须重抛一个预定义的RuntimeException的子类。(请勿回望)

事务注意事项

要根据实际的需求来决定是否要使用事务,最好是在编码之前就考虑好,不然到以后就难以维护;

如果使用了事务,请务必进行事务测试,因为很多情况下以为事务是生效的,但是实际上可能未生效!

1:事务@Transactional的使用要放再类的公共(public)方法中,需要注意的是在 protected、private 方法上使用 @Transactional 注解,它也不会报错(IDEA会有提示),但事务无效。

2:事务@Transactional是不会对该方法里面的子方法生效!也就是你在公共方法A声明的事务@Transactional,但是在A方法中有个子方法B和C,其中方法B进行了数据操作,但是该异常被B自己处理了,这样的话事务是不会生效的!反之B方法声明的事务@Transactional,但是公共方法A却未声明事务的话,也是不会生效的!如果想事务生效,需要将子方法的事务控制交给调用的方法,在子方法中使用rollbackFor注解指定需要回滚的异常或者将异常抛出交给调用的方法处理。一句话就是在使用事务的时候子方法最好将异常抛出!

3:事务@Transactional由spring控制的时候,它会在抛出异常的时候进行回滚。如果自己使用catch捕获了处理了,是不生效的,如果想生效可以进行手动回滚或者在catch里面将异常抛出,比如throw new RuntimeException();。

总结:

  1. Spring事务管理是根据异常来进行回滚操作;
  2. Spring与Mybatis整合时,虽然在Service方法中并没有check异常,但是如果数据库有异常发生,默认会进行事务回滚。
  3. Spring 如果不添加rollbackFor等属性,Spring碰到Unchecked Exceptions都会回滚,不仅是RuntimeException,也包括Error。
  4. 如果在事务方法中捕获异常并进行处理,一定要继续抛出异常并在Spring事务管理中进行rollbak-for配置。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值