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 @ 2022-02-22 22:18  站在巨人肩上的人  阅读(254)  评论(0编辑  收藏  举报