hibernate INTERNAL@TRANSACTIONAL(READOnly=FALSE,ROLLBACKFor=Exception.class)中的故障回滚整个外部持久性

6ljaweal  于 2022-11-14  发布在  其他
关注(0)|答案(1)|浏览(119)

我在一个带注解的类@Transactional中有一个作业方法。此作业方法调用内部方法以持久化单个记录。如果我在结果集处理的中间位置模拟以下内部update()方法中的错误,我会看到此异常之前/之后的所有成功记录在作业完成后不会被保存。为什么会这样呢?所有外部持久性都应该保留,但失败的单个记录除外。仅内部的update就有rollbackFor

@Service("mailService")
@Transactional
@EnableScheduling
public class MailServiceImpl implements MailService {

  @Override
  @Scheduled(cron = "${mail.cron.pubmed.autosynch.job}")
  public void autoSynchPubMedJob() {
     //... Fetch result set
     for (Result r: resultset) {
        try {
           pubService.updatePublication(r);
        } catch (Exception e) {
           // Silently log and continue
           log.error("Error on record: ", e);
        }
     }
  }

updatePublication方法,这是具有rollbackFor的方法:

@Override
@Transactional(readOnly = false, rollbackFor = Exception.class)
public void updatePublication(Publication publication) throws Exception {
    dao.update1(..);
    dao.update2(..);
    // Simulate exception for a specific record for testing
    if (publication.getId() == 123) {
       throw new Exception("Test Exception");
    }
}

结果:在作业完成结束时,没有成功的数据持续存在。应该有部分持久性(对于其他成功的记录)。当我删除这个异常模拟时,所有数据都在最后成功持久化。此外,如果删除内部调用的rollbackFor,则所有数据都将持久化。

31moq8wy

31moq8wy1#

ProBaby,因为它使用现有事务。尝试使用propagation = REQUIRES_NEW打开一个新的。
注意:如果从同一服务调用该方法,则不会打开新的事务。您应该对另一个@Service使用自引用调用或提取逻辑。

相关问题