SpringBoot JPA单方法内多更新操作如何实现Transactional事务控制
问题原因分析
- 你的
userdefined_method未开启全局事务,内部调用的deleteById、save方法各自独立开启事务,每个方法执行完成后会立即提交,后续环节报错时已提交的事务无法回滚 - Spring事务基于AOP动态代理实现,private方法无法被代理,即使加了
@Transactional也不会生效 - 如果是同类内部直接调用方法,会绕过代理对象,也会导致事务注解失效
解决方案
按照以下步骤调整即可实现全局事务控制,任意环节报错所有已执行的数据库操作全部回滚:
- 将
userdefined_method的访问修饰符从private改为public,给方法添加@Transactional注解,如果需要支持所有异常类型回滚可以配置rollbackFor属性
import org.springframework.transaction.annotation.Transactional; @Transactional(rollbackFor = Exception.class) public void userdefined_method(){ // part1 若干业务逻辑代码 orderService.deleteById(123); // 该方法已标注@Transactional // part2 若干业务逻辑代码 orderService.save(order); // 该方法已标注@Transactional // part3 若干其他业务逻辑代码 }
- 确认内部调用的
deleteById、save方法的事务传播行为为默认的Propagation.REQUIRED(Spring默认值无需额外配置),该传播行为会让子方法自动加入当前已存在的全局事务,不会新开独立事务 - 检查
@Transactional注解导入的包为org.springframework.transaction.annotation.Transactional,不要误导入javax.transaction包下的同名注解 - 如果
userdefined_method和被调用的增删方法属于同一个Service类,不要直接用this.方法名调用,需要通过注入的代理对象调用,或者将userdefined_method抽到独立的Service层方法中,避免同类内部调用绕过代理导致事务失效
验证说明
调整完成后,userdefined_method启动时会开启一个全局事务,内部所有增删操作都加入该事务,任意环节抛出异常时全局事务会统一回滚,不会出现部分操作已提交的问题。
内容的提问来源于stack exchange,提问作者Nomad
相关产品推荐
相关产品推荐

