我有一个公共数据库,供两个不同的应用程序使用(不同的技术,不同的部署服务器,它们仅使用相同的数据库)。
我们称它们为application #1
和application #2
。
假设我们有以下情况:
application #2
是在Spring Boot中开发的,主要用于从数据库中读取数据application #2
从数据库中检索一个项目application #1
更改了该项目application #2
再次检索同一项目,但更改不可见通过阅读许多文章,我了解到:
application #2
检索项目时,Hibernate将其存储在第一级缓存中application #1
对项目所做的更改是外部更改,而Hibernate并未意识到这些更改,因此不会更新缓存(在数据库中进行手动更改时也会发生这种情况)所以,我的问题是,您是否可以在不显式调用em.refresh(entity)
的情况下,强制Hibernate在每次读取(或使其进入数据库)实体时刷新它们?问题在于,application1
中的业务逻辑模块被用作application1
中的依赖项,因此我只能调用服务方法(即,我无权访问entityManager
或{{ 1}}参考文献。
答案 0 :(得分:1)
在可重复读取级别隔离中运行时,休眠L1高速缓存大致等效于数据库事务。基本上,如果您读取/写入一些数据,则下次在同一会话的上下文中进行查询时,您将获得相同的数据。此外,在同一过程中,会话彼此独立运行,这意味着2个会话正在查看L1缓存中的不同数据。
如果您使用的是可重复读或更少,那么您就不必担心L1高速缓存,因为不管ORM(或没有ORM),您都可能会遇到这种情况。
我认为您只需要在这里考虑L2缓存。 L2高速缓存存储数据,并假定只有休眠模式正在访问数据库,这意味着如果数据库中发生某些更改,休眠模式可能不会知道它。如果仅禁用L2缓存,则会对您进行排序。
答案 1 :(得分:0)
好吧,如果您无法访问休眠会话,您将一无所获。您要执行的任何操作都需要会话访问权限。例如,您可以像这样读取实体后将其从缓存中删除:
session.evict(entity);
或此
session.clear();
但首先,您需要一个会话。由于仅调用服务,因此需要在服务后创建服务端点以清除会话缓存,或修改现有端点来做到这一点。
答案 2 :(得分:0)
您可以尝试使用StatelessSession
,但是会丢失cascading
和其他东西。
答案 3 :(得分:0)
您可以强制启动新事务,因此将不会从高速缓存中读取休眠状态,并且将从数据库中重做读取。
您可以通过这种方式注释功能
@Transactional(readOnly = true, propagation = Propagation.REQUIRES_NEW)
请求新事务,系统将生成新的休眠会话,因此数据将不在缓存中。