@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);
}
当 methodB()
中的 dao.insert(e)
导致主键冲突并抛出 ConstraintViolationException
时,它是RuntimeException
,由于我使用了 noRollbackFor
属性,我希望事务仍会提交。但是我观察到外部事务(在 methodA
上)仍然被 HibernateTransactionManager
回滚并带有消息
org.springframework.transaction.UnexpectedRollback Exception: Transaction rolled back because it has been marked as rollback-only
我发现报告了类似的问题,但不完全是这个问题。
最佳答案
一旦捕获到异常,Hibernate Session应该被丢弃并且事务应该被回滚:
If the Session throws an exception, the transaction must be rolled back and the session discarded. The internal state of the Session might not be consistent with the database after the exception occurs.
因此,noRollbackFor
适用于可能引发异常的服务和 DAO 层。假设您有一个通过 Hibernate DAO 写入数据库并通过 emailService 发送电子邮件的 gatewayService。如果 emailService 抛出 SendMailFailureException
,您可以指示 gatewayService 在捕获此异常时不要回滚:
@Transactional(noRollbackFor=SendMailFailureException.class)
public void saveAndSend(Entity e){
dao.save(e);
emailService.send(new Email(e));
}
关于java - @Transactional (noRollbackFor=RuntimeException.class) 不会阻止在 RuntimeException 上回滚,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27849968/