2016-09-20 55 views
1

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

  • Hazelcast 3.6.5与hazelcast-hibernate4
  • 休眠集群

配置在persistence.xml中的4.3.10

  • 3服务器:

    <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查询是针对数据库发送(如在日志中观察到的)。清除一个节点上的查询缓存导致所有NODES请求来自数据库的新数据。

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

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

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

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

    在此先感谢!

  • 回答

    0

    Hibernate只提供第二级缓存SPI。 Ehcache模块由Ehcache团队维护,与Infinispan和Hazelcast一样,所以来自Hazelcast团队的人可能知道是什么原因导致了这个问题。

    既然你问了hibernate.cache.use_minimal_puts,我会回答你的问题的这一部分。此配置属性优化了二级缓存操作以最大限度地减少写入,而您为更频繁的读取支付价格。

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