分享一个事务不生效的bug和相关的解决方案,目前保存后置事件是不支持方法内部的事务回滚的,参考下图
第502行更新后下一行立即报错,这时事务没有回滚
检查公共的调用方法发现后置事件是被try catch了,后置事件报错会导致之前的save方法回滚,所以表单数据是没有保存的,但是这个afterSaveData本身因为被try catch所以没有回滚,导致数据库被更新,见下图
如果把commonService.afterSaveData(module, formData, isNew);这个方法放到try catch外面去就没有问题,整个方法包含afterSaveData都会回滚,但是这里是公共方法不敢轻易去改,所以先想其他解决办法,首先想到的就是给这个方法单独加事务,如下
但实际结果不行,因为@Transaction这个注解默认会用上一层的事务,那上一层已经被try catch了,自然事务无法生效,所以就想着应该要重新开一个子事务,查看注解如下
把事务改成@Transactional(rollbackFor = Exception.class,propagation = Propagation.NESTED)再试下
结果依然不行,然后想到之前看过的事务的几种失效场景,其中一种就是事务是在获取对象的时候通过aop拿取的
这个service在通用的save方法就已经拿了一次,所以事务在哪儿就已经加上去了,下图位置
所以现在解决方案就是
第一种:在另外一个类去加事务,然后调用
第二种:在本类写方法,然后重新获取下service,重新触发下aop
上面两种方案测试都没有问题