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

标签 java spring hibernate jpa transactions

@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/

相关文章:

java - 无法使用 JPA 工具从数据库生成实体

java - MethodVisitor的(api, MethodVisitor)构造函数,是否只需要读取

java - spring data批量保存时如何判断违规实体

java - Spring MVC PUT 请求返回 405 方法不允许

java - Hibernate Criteria in Clause 在 1 个查询中有 2 个条件

java - hibernate/ Spring 3 : could not initialize proxy - no Session

java - 如何以自定义对象作为输入参数调用Oracle存储过程

java - 使用camel中的send方法发送对象

Java蓝牙套接字重新启动后不接受连接

java - Spring Data JPA 与 QueryDSL、聚合函数的计数问题