Hibernate + Hazelcast Query Cache有时候不会刷新

时间:2016-09-20 13:12:00

标签: hibernate caching hazelcast

当我们使用Hazelcast作为缓存提供程序时,我们发现Hibernate查询缓存存在一个奇怪的问题。这是我们的设置:

  • Hazelcast 3.6.5 with hazelcast-hibernate4
  • Hibernate 4.3.10
  • 群集中的3台服务器

persistence.xml中的配置:

   <properties>
        <property name="javax.persistence.sharedCache.mode" value="DISABLE_SELECTIVE"/>

        <property name="hibernate.cache.region_prefix" value="custom-pu"/>
        <property name="hibernate.enable_lazy_load_no_trans" value="true"/>
        <property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect"/>
        <property name="hibernate.default_batch_fetch_size" value="50"/>
        <property name="hibernate.jdbc.batch_size" value="50"/>
        <property name="hibernate.event.merge.entity_copy_observer" value="log"/>

        <property name="hibernate.session_factory_name" value="customSessionFactory"/>

        <property name="hibernate.cache.hazelcast.configuration_file_path"
                  value="${config.dir}/custom-hazelcast.xml"/>
        <property name="hibernate.cache.hazelcast.instance_name" value="customInstance"/>
        <property name="hibernate.cache.hazelcast.use_native_client" value="false"/>
        <property name="hibernate.cache.region.factory_class"
                  value="com.hazelcast.hibernate.HazelcastLocalCacheRegionFactory"/>
        <property name="hibernate.cache.hazelcast.shutdown_on_session_factory_close" value="false"/>
        <property name="hibernate.cache.use_second_level_cache" value="true"/>
        <property name="hibernate.cache.use_query_cache" value="true"/>

        <property name="javax.persistence.validation.group.pre-persist" value="javax.validation.groups.Default"/>
        <property name="javax.persistence.validation.group.pre-update" value="javax.validation.groups.Default"/>
    </properties>

有时,用户更新某些数据,同一节点上的用户或另一个节点上的用户看不到更新 - 没有针对数据库发送SQL查询(如日志中所示)。清除一个节点上的查询缓存会导致所有节点从数据库请求新数据。

我们首先通过数据库视图支持的实体列表观察到这一点,但是使用@Synchronized正确地注释了视图,我们在调试期间看到Hibernate正确地检查了所提到的表的区域。如果查询缓存停止工作,则缓存超时(在hazelcast.xml中配置)会导致最终显示正确的结果。

在日志中我们看到,一旦查询缓存停止工作,时间戳缓存报告@Synchronized中提到的区域的缓存数据早于查询缓存结果,因此Hibernate不会丢弃旧条目并请求新的数据

我现在多次检查了persistence.xml中的配置,看到我们没有激活这个属性:hibernate.cache.use_minimal_puts - 会有所不同(我当然可以简单地应用它,但我想知道为什么这将解决我们的问题。)

我们在这里不知所措,因为我们不知道如何正确地重现问题,我们不知道是什么原因造成的。另外,Hazelcast的hibernate-cache集成并不是很冗长,因此很难看出发生了什么......

提前致谢!

1 个答案:

答案 0 :(得分:0)

Hibernate仅提供二级缓存SPI。 Ehcache模块由Ehcache团队维护,与Infinispan和Hazelcast一样,因此Hazelcast团队的某个人可能知道导致此问题的原因。

由于您询问hibernate.cache.use_minimal_puts,我会回答您问题的这一部分。此配置属性优化二级缓存操作以最小化写入,同时为更频繁的读取付出代价。

此设置对群集缓存很有用,因此Hazelcast可能会从中受益。通常,第二级缓存提供程序会自动为集群环境启用它。