1

我的应用程序有一项服务将在内部轮询作业输出。它会轮询直到作业状态从“进行中”变为“已完成”。另一个系统将在处理作业后将作业状态更新为“已完成”。

这里的问题是,第一次从数据库轮询作业状态时,状态为“进行中”。但后来即使工作状态被其他进程更改,我仍然将其视为“进行中”。问题不在于 DB 隔离级别(可重复读取),因为我的休眠查询是在事务外执行的。我怀疑结果被缓存了,当在同一个会话中执行相同的查询时,我得到了缓存的结果。

当在同一个会话中多次执行相同的查询时,如何从数据库中获取更新的数据。

问候, 钱杜

4

1 回答 1

2

更新

根据评论,它是一个使用 Spring JPA 数据的 Spring Boot 应用程序。service班级每 5 分钟检查一次状态,其中包含一个循环。即,它实际上是在同一个事务中,即同一个会话。

因此,除非我们调用,否则refresh()我们evict() and reload将无法从数据库中看到更新的状态。

但问题是CrudRepository没有公开任何refresh()我们可以调用的方法entity manager

所以选项是CrudRepository添加一个方法say refreshEntity(...)。此方法将在内部调用entityManager.refresh(). 最后,service循环可以调用此refreshEntity(..)方法并获取更新的数据。

举个例子:

public interface MyStatusRepository {
   void refreshEntity(StatusEntity se);
}

public interface StatusRepository extends CrudRepository<StatusEntity, Long>, MyStatusRepository {
    ...
}

@Repository
public class MyStatusRepositoryImpl implements MyStatusRepository {
    @PersistenceContext
    private EntityManager entityManager;

    @Override
    public void refreshEntity(StatusEntity se); {
        entityManager.refresh(se);
    }
    ...
}

更多关于扩展存储库的信息可以在上面的链接中找到。

另一个选项是,而不是扩展,在类本身中CrudRepository自动装配并调用它。这也有效,但会偏离现有设计。entityManagerservicerefresh()

于 2016-03-30T15:39:36.737 回答