记录AOP中切面类的事务传播性引发的一个小问题

记录一个Spring事务在@aspect切面类的传播性事件

使用spring的AOP做一个切面日志记录是目前大大小小项目经常使用的一个功能
最近在做公司的一个费用管理系统的时候有一个功能是要记录中台业务操作/审核费用单据的所有动作日志 包括新增录入,审核,拒审,财务确认等操作。
好,目的很明确,直接开始码代码,定义注解,定义切面类,使用@pointcut将注解绑定,
记录AOP中切面类的事务传播性引发的一个小问题
使用环绕增强的@around方法拦截指定方法,劈里啪啦一切就绪,再在我对应的业务接口上安排好我的注解,妥妥的…
记录AOP中切面类的事务传播性引发的一个小问题结果运行费用单录入的操作的时候,触发数据库非空字段警告,数据落库失败,正想着去看日志记录的异常是什么样的,结果发现日志也没记录上去,好家伙业务方法事务回滚连带着切面类的方法也回滚了。。。

好,为了证实事务的传播性是否涉及到切面,我想用debug一探究竟,spring事务是通过TransactionInterceptor进行拦截,然后再通过反射进行相关逻辑处理,
记录AOP中切面类的事务传播性引发的一个小问题那么我们在invokeWithinTransaction方法里面打个断点,看看方法是否进去
记录AOP中切面类的事务传播性引发的一个小问题调用接口
记录AOP中切面类的事务传播性引发的一个小问题方法先进入invokeWithinTransaction的断点,再进入业务方法,然后再进入切面方法里面,这就说明切面类和主业务公用一个事务。
因为spring默认使用Propagation.REQUIRED,AOP代理创建的一个类在外层业务的事务包裹中加入了当前事务,那么解决方法是什么呢,选择Propagation.REQUIRED_NEW?
不行,因为切面@around捕获到了当前业务的异常信息,它必须要重新抛出去,让更外层接收到,再次在切面类中创建事务它还是会回滚
记录AOP中切面类的事务传播性引发的一个小问题那么最终解决办法我在图片里面也表明了,当然是使用TaskExecutor重新创建一个线程让它去跑日志记录的方法啦,管你什么事务,换个线程解决~

以前做日志记录都是做请求日志记录或者系统对接的接口日志记录,这还是第一次做业务层的日志记录,第一次遇到事务切面相关的问题,记录一下这个问题