如何强制Hibernate读取外部数据库更改

时间:2019-07-05 08:36:03

标签: java hibernate spring-boot

我有一个公共数据库,供两个不同的应用程序使用(不同的技术,不同的部署服务器,它们仅使用相同的数据库)。

我们称它们为application #1application #2

假设我们有以下情况:

  • 数据库包含一个名为 items 的表(无关紧要的内容)
  • application #2是在Spring Boot中开发的,主要用于从数据库中读取数据
  • application #2从数据库中检索一个项目
  • application #1更改了该项目
  • application #2再次检索同一项目,但更改不可见

通过阅读许多文章,我了解到:

  • application #2检索项目时,Hibernate将其存储在第一级缓存中
  • application #1对项目所做的更改是外部更改,而Hibernate并未意识到这些更改,因此不会更新缓存(在数据库中进行手动更改时也会发生这种情况)
  • 您不能禁用Hibernate的一级缓存。

所以,我的问题是,您是否可以在不显式调用em.refresh(entity)的情况下,强制Hibernate在每次读取(或使其进入数据库)实体时刷新它们?问题在于,application1中的业务逻辑模块被用作application1中的依赖项,因此我只能调用服务方法(即,我无权访问entityManager或{{ 1}}参考文献。

4 个答案:

答案 0 :(得分:1)

在可重复读取级别隔离中运行时,休眠L1高速缓存大致等效于数据库事务。基本上,如果您读取/写入一些数据,则下次在同一会话的上下文中进行查询时,您将获得相同的数据。此外,在同一过程中,会话彼此独立运行,这意味着2个会话正在查看L1缓存中的不同数据。

如果您使用的是可重复读或更少,那么您就不必担心L1高速缓存,因为不管ORM(或没有ORM),您都可能会遇到这种情况。

我认为您只需要在这里考虑L2缓存。 L2高速缓存存储数据,并假定只有休眠模式正在访问数据库,这意味着如果数据库中发生某些更改,休眠模式可能不会知道它。如果仅禁用L2缓存,则会对您进行排序。

进一步阅读-Short description of hibernate cache levels

答案 1 :(得分:0)

好吧,如果您无法访问休眠会话,您将一无所获。您要执行的任何操作都需要会话访问权限。例如,您可以像这样读取实体后将其从缓存中删除:

session.evict(entity);

或此

session.clear();

但首先,您需要一个会话。由于仅调用服务,因此需要在服务后创建服务端点以清除会话缓存,或修改现有端点来做到这一点。

答案 2 :(得分:0)

答案 3 :(得分:0)

您可以强制启动新事务,因此将不会从高速缓存中读取休眠状态,并且将从数据库中重做读取。

您可以通过这种方式注释功能

@Transactional(readOnly = true, propagation = Propagation.REQUIRES_NEW)

请求新事务,系统将生成新的休眠会话,因此数据将不在缓存中。