Spring嵌套事务标记为rollbackonly,未检查异常

Spring嵌套事务标记为rollbackonly,未检查异常,spring,hibernate,transactions,Spring,Hibernate,Transactions,我对Spring和transactions相当陌生。我相信这个问题以前有人问过,但我仍然想不出正确的解决方法 我正在使用Spring和hibernate。我有一个这样的服务方法: @Transactional public void processPendingReport(Report report) { try { // Do processing stuff, update report object state reportDAO.save(report); }

我对Spring和transactions相当陌生。我相信这个问题以前有人问过,但我仍然想不出正确的解决方法

我正在使用Spring和hibernate。我有一个这样的服务方法:

@Transactional
public void processPendingReport(Report report) {
  try {
    // Do processing stuff, update report object state
    reportDAO.save(report);
  } catch (Exception e) {
    reportDAO.markReportAsFailed(report);
  }
}
如果在处理过程中发生RuntimeException,则将抛出“标记为rollbackOnly的事务”RollbackException,从而使报表不会标记为failed(尽管我希望如此)

我尝试过使用@Transactional(norollboor=Exception.class),但仍然遇到同样的问题。。有什么建议吗?这可能是配置问题吗?

如果在
reportDAO.save()
reportDAO.markReportAsFailed()
中发生数据库异常(例如约束冲突),则无论您在应用程序级别上做什么,事务都将在数据库级别回滚

如果为
reportDao.markReportAsFailed()
创建新事务时
reportDao.save()
失败,则仍然可以将报告标记为失败。由于
ReportDAO
被注释为
@Transactional
,只需从服务方法中删除
@Transactional
注释即可。您还可以将
reportDAO.save()
实现更改为使用数据库函数或存储过程来包装insert语句并捕获数据库级别的任何异常


reportDAO类是否也标记为@Transactional?reportDAO.save和reportDAO.markReportAsFailed使用了什么事务传播?reportDAO在类级别标记为@Transactional。applicationContext.xml中没有explixit tx:advice声明,因此它应该是默认的、必需的传播级别您提到的这个回滚异常,是ajavax.persistence.rollbackException吗?如果是这样,它应该只出现在事务结束时,即提交时。是否可以在save方法之前检查事务状态,以检查它是否尚未标记为回滚?还是“markReportAsFailed”方法是引发回滚异常的方法?我认为您应该尝试使用reportDAO.markReportAsFailed transaction with REQUIRES_NEW,因为您希望父事务作为回滚,但markReportAsFailed无法提交。错误不会发生在数据库级别,而是发生在代码中。因此,在“//do processing stuff”部分,我有时会得到一个NullPointerException,例如,整个(外部)事务会回滚,这不允许MarkReportAs无法执行并实际更改报告状态。