Spring嵌套服务调用仅外层Repo数据保存内层未持久化问题咨询
异常行为可能原因及排查方向
首先注意你贴的代码里存在笔误:Service1类中@Autowired被拼写为@Aautowired,如果是实际代码的问题请先修正,若只是粘贴时的疏漏可忽略。以下是对应问题的具体排查点:
- 异常吞服+事务回滚规则不匹配:Spring
@Transactional默认仅对RuntimeException和Error触发回滚。如果Service2的doBussinesLogic方法内部抛出了Checked Exception(如自定义非运行时异常、IO异常等),且该异常被方法内部的try-catch捕获消化、没有抛到Service1的update方法外层,就会出现:Service2的操作触发事务回滚,但Service1的事务感知不到异常正常提交,最终仅s1repo的数据持久化成功。
排查方式:检查
doBussinesLogic内部是否有吞异常的逻辑,打印全量异常栈确认抛出的异常类型,核对@Transactional注解是否配置了rollbackFor覆盖业务中所有需要触发回滚的异常。
- 事务传播行为配置错误:如果Service2的
doBussinesLogic方法单独加了@Transactional注解,且传播行为配置为REQUIRES_NEW:Service2的事务是完全独立的,内部异常只会回滚自身事务,只要异常没有抛到外层,Service1的事务依然会正常提交;如果传播行为配置为NOT_SUPPORTED,Service2的操作根本不会运行在事务中,saveAll未生效和事务无关需要单独排查逻辑。
排查方式:核对所有业务方法
@Transactional注解的propagation属性,确认传播行为符合预期。
- Hibernate持久化操作未实际同步:Hibernate存在一级缓存机制,若你操作的users对象为游离态、或者flush模式配置为MANUAL且未手动触发flush,事务提交前可能不会将修改同步到数据库;另外如果users集合为空、实体类映射配置错误(如主键生成策略不匹配、字段和数据库列映射错误),也会导致
saveAll执行但无实际数据写入。
排查方式:开启Hibernate SQL打印配置,观察是否实际输出了对应的INSERT/UPDATE语句,确认
saveAll执行前users集合不为空,核对Service2对应实体类和数据库表的映射关系是否正确。
- Service2方法未被Spring AOP代理:你当前代码中
doBussinesLogic是包访问权限,如果方法不是public修饰、或者Service2实例不是Spring容器管理的Bean(比如你手动new的Service2对象而非@Autowired注入),即使加了@Transactional注解也不会生效,对应的操作如果在独立连接中执行,异常回滚也不会影响Service1的事务。
排查方式:确认Service2是Spring容器托管的Bean,
doBussinesLogic方法为public修饰,且是通过注入的Service2实例调用方法,不是类内部的this调用。
内容的提问来源于stack exchange,提问作者user3528865
相关产品推荐
相关产品推荐

