@Transactional (noRollbackFor=RuntimeException.class)
public void methodA (Entity e){
service.methodB(e);
}
---以下服务方法---
@Transactional (propagation=Propagation.REQUIRES_NEW, noRollbackFor=RuntimeException.class)
public void methodB (Entity e){
dao.insert(e);
}
当dao.insert(e)
中的methodB()
导致主键违规并抛出ConstraintViolationException
,这是RuntimeException
的子类时,我希望该事务仍然可以提交我使用的noRollbackFor
属性。但是我发现外部事务(在methodA
上)仍然被HibernateTransactionManager
回滚并带有消息
org.springframework.transaction.UnexpectedRollback异常: 事务已回滚,因为它已标记为仅回滚
我发现了类似的问题,但不完全是这个问题。
答案 0 :(得分:11)
捕获到异常后,应丢弃Hibernate Session并回滚事务:
如果Session抛出异常,则必须滚动事务 返回,会话被丢弃。会话的内部状态 发生异常后,可能与数据库不一致。
因此,noRollbackFor
适用于可能引发异常的Service和DAO层。假设您有一个 gatewayService ,它通过Hibernate DAO写入数据库,并通过 emailService 发送电子邮件。如果emailService抛出SendMailFailureException
,您可以指示 gatewayService 在它捕获此异常时不回滚:
@Transactional(noRollbackFor=SendMailFailureException.class)
public void saveAndSend(Entity e){
dao.save(e);
emailService.send(new Email(e));
}