如何在Service类中回滚事务?抛出异常后update操作未回滚如何解决?
问题根因分析
- 你当前使用的
@TransactionAttribute是EJB组件的事务注解,Spring生态下默认不识别该注解,导致purgeUser方法声明的REQUIRES_NEW事务完全未生效 - 由于外层
purgeUser无事务,调用basicEM.update()时会触发BasicEM类上声明的独立事务,update执行完成后该事务会立即提交,后续抛出异常时无法回滚已提交的事务 - 补充代码小问题:
UserManager构造方法名错误写成了ApplicantInfoManager,异常抛出语法throw New应为throw new
解决方案
- 将
UserManager类的事务注解替换为Spring原生的@Transactional,配置对应传播行为和回滚规则
@Service public class UserManager implements IUserManager { private final IBasicEM basicEM; // 修正构造方法名 public UserManager(IBasicEM basicEM) { this.basicEM = basicEM; } @Override // 替换为Spring事务注解,配置 REQUIRES_NEW 传播行为,全异常回滚 @Transactional(value = "transactionManager", propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class) public boolean purgeUser(Long id) throws Exception { //business logic basicEM.update(entity); if(/*业务判断条件*/) { // 修正异常抛出语法 throw new RollBackException("//message"); } //business logic return true; } }
- 确认自定义
RollBackException的规则:如果你的RollBackException是继承Exception的受检异常,必须在@Transactional中配置rollbackFor = Exception.class(上述代码已经包含该配置),如果是继承RuntimeException的非受检异常,默认即可触发回滚 - 确认事务生效场景:
purgeUser方法必须是通过Spring注入的UserManager实例调用,不能是类内部的直接调用(内部调用不会走Spring代理,事务注解不生效)
调整后basicEM.update会加入purgeUser开启的外层事务,后续抛出异常时会触发整个事务回滚,update的修改操作也会被撤销。
内容的提问来源于stack exchange,提问作者mahfuj asif
相关产品推荐
相关产品推荐

