Spring Boot多数据源下saveAndFlush()失效,报无事务异常
多数据源写入失败(TransactionRequiredException)解决方案
核心问题定位
你的从数据源(Power)事务管理器配置存在错误,导致事务无法正确绑定到从数据源的EntityManagerFactory,进而引发无事务异常。
具体修复步骤
1. 修正从数据源事务管理器的EntityManagerFactory引用
查看PowerPersistenceConfiguration中的powerTransactionManager方法,你错误地引用了主数据源的entityManagerFactory,而非从数据源自身的entityManagerFactorySecondary。
修改前代码:
@Bean( name = "powerTransactionManager") public PlatformTransactionManager powerTransactionManager( final @Qualifier("entityManagerFactory") LocalContainerEntityManagerFactoryBean powerEntityManagerFactory) { return new JpaTransactionManager(powerEntityManagerFactory.getObject()); }
修改后代码:
@Bean( name = "powerTransactionManager") public PlatformTransactionManager powerTransactionManager( final @Qualifier("entityManagerFactorySecondary") LocalContainerEntityManagerFactoryBean powerEntityManagerFactory) { return new JpaTransactionManager(powerEntityManagerFactory.getObject()); }
2. 确保Repository层事务注解生效
给Power相关Repository补充事务传播行为和回滚规则,确保写入操作被正确包裹:
@Transactional(value = "powerTransactionManager", propagation = Propagation.REQUIRED, rollbackFor = Exception.class) public interface PowerDayDetailsRepository extends JpaRepository<PowerDayDetails, ...> { }
3. 优化控制器层事务边界(可选但推荐)
控制器方法中同时执行deleteAll()和saveAll(),需将这两个操作置于同一事务中,避免部分执行的情况。可在控制器方法上添加事务注解:
@PostMapping("/power/powerdaydetails") @Transactional("powerTransactionManager") public boolean insertPowerDayDetails(@RequestBody List<PowerDayDetails> powerDayDetails){ myLog.info("POST /power/powerdaydetails"); powerDayDetailsRepository.deleteAll(); List<PowerDayDetails> lines = powerDayDetailsRepository.saveAllAndFlush(powerDayDetails); myLog.info("Update size: " + lines.size()); myLog.info("Received data: " + powerDayDetails.size()); return lines.size() == powerDayDetails.size(); }
更规范的做法是将业务逻辑抽离到Service层,在Service方法上添加事务注解,控制器仅负责接收请求和返回响应。
验证修复
修改完成后重启项目,调用/power/powerdaydetails接口,此时saveAllAndFlush()应能正常执行,数据会正确写入从数据库。
内容的提问来源于stack exchange,提问作者Rick
相关产品推荐
相关产品推荐

