@Transactional 中的 Spring Data JpaRepository saveAndFlush 不起作用

JuH*_*m89 5 hibernate spring-transactions spring-data-jpa

目前我面临着 Spring-Data/Hibernate 的一个问题,我将简要介绍一下。

我正在研究一些简单的报告功能,它从单个表中获取实体作为流。这工作正常,但必须在更长时间运行的事务中发生,因为与数据库的连接需要保持打开状态。在这个事务中,我想不断更新一个 ReportEntity,它跟踪进程的状态和进度。代码看起来基本上是这样的:

    @Async
    @Transactional(isolation = Isolation.READ_UNCOMMITTED)
    public void process(Long reportId, SearchCriteria searchCriteriaTo) {

        ReportEntity report = reportRepository.findById(reportId).get();
        report.setStatus(ReportGenerationStatus.START);
        reportRepository.saveAndFlush(report);

        Stream<RawDataEntity> rawDataEntityStream = this.rawDataRepository
            .findAllFiltered(...);

        report.setStatus(ReportGenerationStatus.GENERATING_REPORT);
        report.setProgress(50);
        reportRepository.saveAndFlush(report);

        ...

        rawDataEntityStream.forEach(() -> DoSomething())

        ...

        report.setStatus(ReportGenerationStatus.FINISHED);
        report.setProgress(100);
    }

Run Code Online (Sandbox Code Playgroud)

我的问题是,根据我的理解, saveAndFlush 应该将 The ReportEntity 的中间步骤写入数据库,但事实并非如此。我正在使用 Posgres DB 并使用 PGAdmin 验证了这一点,并且我还编写了一个不断获取 ReportEntity 的轮询客户端。

    @Transactional(readOnly = true)
    public ReportEto getReportByKey(UUID key) {
        // entityManager.clear();
        ReportEntity reportEntity = this.reportRepository.findByKey(key);
        return getBeanMapper().map(reportEntity, ReportEto.class);
    }
Run Code Online (Sandbox Code Playgroud)

但是状态“GENERATING_REPORT”不会写入数据库。只有在最终提交后,状态才会更新为 FINSIH。我试图将隔离级别设置为“READ_UNCOMMITTED”,但这也没有效果。然而,休眠调试日志建议触发更新:

o.h.e.i.DefaultMergeEventListener        : EntityCopyObserver strategy: disallow
o.h.e.i.AbstractFlushingEventListener    : Processing flush-time cascades
o.h.e.i.AbstractFlushingEventListener    : Dirty checking collections
o.h.e.i.AbstractFlushingEventListener    : Flushed: 0 insertions, 1 updates, 0 deletions to 1 objects
o.h.e.i.AbstractFlushingEventListener    : Flushed: 0 (re)creations, 0 updates, 0 removals to 0 collections
o.hibernate.internal.util.EntityPrinter  : Listing entities:
o.hibernate.internal.util.EntityPrinter  : com.capgemini.cusmesonlinereporting.reportmanagement.dataaccess.api.ReportEntity{downloadLink=null, externalUserId=MMUSTER, modificationCounter=0, creationTimestamp=2020-03-26T07:21:03.421700Z, name=2018-1-1_2020-3-23, progress=0, id=1000019, key=ecb0955f-b838-4f30-ac1f-dc94763ac810, status=GENERATING_REPORT}
org.hibernate.SQL                        : update Report set modificationCounter=?, creationTimestamp=?, downloadLink=?, externalUserId=?, key=?, name=?, progress=?, status=? where id=? and modificationCounter=?
Hibernate: update Report set modificationCounter=?, creationTimestamp=?, downloadLink=?, externalUserId=?, key=?, name=?, progress=?, status=? where id=? and modificationCounter=?
Run Code Online (Sandbox Code Playgroud)

我可以继续使用“REQUIRE_NEW”事务对嵌套事务中的 ReportEntity 进行所有更新,但我不想遇到潜在的死锁,因为长时间运行的事务可能会并行执行多次。所以我的问题是:

  1. 为什么 saveAndFlush 在这种情况下不起作用?
  2. 是否有不涉及创建嵌套事务的解决方法?