spring事务失效

遇到的问题

​ 前端时间我在做一个父子事务嵌套的时候,出现了子事务失效。在同类的子事务上加事务注解一直都不能创建事务,后来发现是子事务失效了。下面总结一下事务失效情况和解决经验

事务失效有如下几种情况:

  1. 没有Transaction注解
  2. 事务没有抛出RuntimeException异常到方法上
  3. 方法内抛出RuntimenException的父类异常,也就是Error、Exception等
  4. 同类方法中相互调用,事务失效
  5. final关键词修饰方法
  6. 非public关键词修饰方法

造成这么多种类的事务失效的主要原因是spring的动态代理,原因如下:

  1. 动态代理方法的异常抓取

    默认只抓取RuntimeException,所以发生异常前的执行的crud操作还是会被提交的

    可以通过@Transaction 的 roolbackfor属性来指定其他异常

  2. 哪些方法能被动态代理

    spring的aop代理,只能代理public访问级别的方法,其中final等关键修饰的方法是不能被代理的。

  3. 怎么调用代理的方法

    spring的aop代理机制,同类的方法之间调用,调用的方法是不会被代理的。比如A类调用B类方法(其中B的方法带有增强的注解),B类中被调用的方法会被代理并增强。但是在B类增强的方法直接调用B类的其他方法(同样方法带有增强的注解),此方法将不会被增强。

    可以通过(B)AopContext.currentProxy()来解决此问题,该操作会拿到当前代理类,然后就可以调用想调用的方法。

事务失效解决流程

​ 结合此次经验,事务失效总结分为一下三部

  1. 检查方法关键字,判断方法是否被代理
  2. 在方法上打断点 执行TransactionAspectSupport.currentTransactionStatus(),获取当前方法的事务状态,没有事务将会抛出异常。判断父子事务,只用判断对象是不是一个,也就是地址是不是相同。
  3. 当上面可以获得事务对象,说明当前存在事务,通过事务对象地址来判断是哪里不存在事务,父子方法调用,子方法没有注解,父类有,事务还是会公用的。所以我们一步步排除还是容易查找出来。
posted @   站在巨人肩上的人  阅读(266)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示