@Transactional(noRollbackFor = RuntimeException.class)不会阻止RuntimeException上的回滚

The*_*gle 9 java spring hibernate jpa transactions

@Transactional (noRollbackFor=RuntimeException.class)
public void methodA (Entity e){
   service.methodB(e);
}
Run Code Online (Sandbox Code Playgroud)

---以下服务方式---

@Transactional (propagation=Propagation.REQUIRES_NEW, noRollbackFor=RuntimeException.class)
public void methodB (Entity e){
   dao.insert(e);
}
Run Code Online (Sandbox Code Playgroud)

dao.insert(e)in in methodB()导致主键违规并抛出a ConstraintViolationException,这是一个子类时RuntimeException,我希望事务仍然因为noRollbackFor我使用的属性而提交.但是我发现外部事务(on methodA)仍然被HibernateTransactionManager消息回滚

org.springframework.transaction.UnexpectedRollback异常:事务已回滚,因为它已被标记为仅回滚

我发现了类似的问题,但不完全是这个问题.

Vla*_*cea 15

捕获异常后,应丢弃Hibernate会话并回滚事务:

如果会话抛出异常,则必须回滚事务并丢弃会话.发生异常后,Session的内部状态可能与数据库不一致.

因此,noRollbackFor适用于可能引发异常的Service和DAO层.假设您有一个通过Hibernate DAO写入数据库的gatewayService,并通过emailService发送电子邮件.如果emailService抛出a SendMailFailureException,则可以指示gatewayService在捕获此异常时不回滚:

@Transactional(noRollbackFor=SendMailFailureException.class)
public void saveAndSend(Entity e){
   dao.save(e);
   emailService.send(new Email(e));
}
Run Code Online (Sandbox Code Playgroud)