Spring JPA @Transactional REQUIRES_NEW事务传播不生效问题
问题根本原因
你遇到的REQUIRES_NEW事务传播配置不生效、日志打印Participating in existing transaction,核心是Spring声明式事务的实现机制限制,具体有两个直接诱因:
- 同类内方法调用不会经过AOP代理:Spring的
@Transactional是基于动态代理织入事务逻辑的,只有通过Spring容器生成的代理对象调用方法时,事务切面才会生效。你在addNewProduct方法中直接调用本类的saveAudit()方法,本质是调用原生this对象的方法,完全绕过了代理对象,方法上的事务注解根本没有被解析执行。 - 事务方法访问权限不符合要求:你定义的
saveAudit()方法没有加public修饰符,使用的是包级默认访问权限,Spring AOP默认只会拦截public修饰的方法,非public方法上的@Transactional注解不会被识别。
额外说明:直接在Controller类上加@Transactional属于分层设计不规范,事务逻辑应该放在业务Service层,Web层只负责请求响应处理,不应该承载事务控制逻辑,但这不是本次配置失效的直接原因。另外代码里ProductreRepository、Auditrepository属于变量拼写错误,会直接导致注入失败,需要修正为和Repository接口名匹配的命名。
修复方案
按照优先级推荐以下修复步骤:
- 将审计日志逻辑抽离到独立的Service类中,通过注入的代理对象调用,从根源避免同类调用绕过代理的问题:
@Service public class AuditService { private final AuditRepository auditRepository; // 构造函数注入 public AuditService(AuditRepository auditRepository) { this.auditRepository = auditRepository; } // 必须加public修饰,明确指定传播级别为REQUIRES_NEW @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class) public void saveAudit() { auditRepository.save(Audit.builder().action("action1").build()); } } - 调整Controller代码,移除类上的
@Transactional注解,注入AuditService调用审计方法,事务控制下沉到Service层:@RestController public class ProductController { private final ProductRepository productRepository; private final AuditService auditService; // 构造注入 public ProductController(ProductRepository productRepository, AuditService auditService) { this.productRepository = productRepository; this.auditService = auditService; } @PostMapping(ApiPaths.PRODUCTS) @ResponseStatus(HttpStatus.CREATED) public ProductDTO addNewProduct() { ProductDTO res = productRepository.save(Product.builder().label("product1").build()); // 调用注入的代理对象的方法,事务切面会正常拦截 auditService.saveAudit(); int h=1/0; // 此处抛出异常只会回滚Product的保存事务,已经提交的Audit事务不受影响 return res; } } - (不推荐)如果不想抽离独立Service,也可以在Controller中注入自身的代理对象,通过代理对象调用
saveAudit()方法,同时把saveAudit改为public修饰,但这种方式不符合分层规范,容易产生循环依赖问题,仅作为临时方案使用。
修复后再运行,saveAudit会正常挂起外层Product保存的事务,开启独立新事务执行审计日志保存并自动提交,后续外层抛出异常时,已经提交的审计日志不会被回滚,符合预期的事务隔离效果。
内容的提问来源于stack exchange,提问作者AHmedRef
相关产品推荐
相关产品推荐

