【问题标题】:hibernate cached query not updated when new record inserted插入新记录时休眠缓存查询未更新
【发布时间】:2011-07-21 14:17:21
【问题描述】:

我们有一个 EHCache 集群、hibernate 和 Mysql。

一切正常。标准搜索被缓存,当集群的其他成员上的记录被修改时,缓存的查询会立即在其他服务器上更新。

但是,我的问题是插入新记录时。在缓存查询过期之前,该表上的缓存查询不知道它。

我可能在我的 EHcache.xml 配置中遗漏了一些东西,但我不知道会是什么。

有什么想法吗?

EHCache.xml 如下:

`

<!--<diskStore path="java.io.tmpdir"/>-->

<!-- means for cache replication -->

<cacheManagerPeerProviderFactory
    class="net.sf.ehcache.distribution.jgroups.JGroupsCacheManagerPeerProviderFactory"
    properties="connect=
        TCP(bind_port=10700):
        S3_PING(...):
        MERGE2(max_interval=30000;min_interval=10000):
        FD_SOCK(start_port=0):
        FD(timeout=3000;max_tries=3):
        VERIFY_SUSPECT(timeout=1500):
        BARRIER():
        pbcast.NAKACK(use_mcast_xmit=false;gc_lag=0;retransmit_timeout=300,600,1200,2400,4800;discard_delivered_msgs=true):
        UNICAST(timeout=300,600,1200):
        pbcast.STABLE(stability_delay=1000;desired_avg_gossip=50000;max_bytes=400K):
        pbcast.GMS(print_local_addr=true;join_timeout=300;view_bundling=true):
        FC(max_credits=2M;min_threshold=0.10):
        FRAG2(frag_size=60K):
        pbcast.STREAMING_STATE_TRANSFER()"
    propertySeparator="::" />    

<!-- default query cache to be used for all queries without an explicit cache -->

<cache
    name="org.hibernate.cache.StandardQueryCache"
    maxElementsInMemory="100"
    eternal="false"
    timeToLiveSeconds="600"
    overflowToDisk="false"
    statistics="true">
    <cacheEventListenerFactory
        class="net.sf.ehcache.distribution.jgroups.JGroupsCacheReplicatorFactory"
        properties="replicateAsynchronously=true, replicatePuts=true,
        replicateUpdates=true, replicateUpdatesViaCopy=false, replicateRemovals=true" />
</cache>    

<!-- timestamps of particular last update time to tables -->

<cache
    name="org.hibernate.cache.UpdateTimestampsCache"
    maxElementsInMemory="5000"
    eternal="true"
    overflowToDisk="false"
    statistics="true">
    <cacheEventListenerFactory
        class="net.sf.ehcache.distribution.jgroups.JGroupsCacheReplicatorFactory"
        properties="replicateAsynchronously=true, replicatePuts=true,
        replicateUpdates=true, replicateUpdatesViaCopy=false, replicateRemovals=true" />
</cache>

<!-- default cache to use for all cacheable entities without an explicit cache -->

<defaultCache
        maxElementsInMemory="10000"
        eternal="false"
        timeToIdleSeconds="600"
        timeToLiveSeconds="600"
        overflowToDisk="false"
        maxElementsOnDisk="10000000"
        diskPersistent="false"
        diskExpiryThreadIntervalSeconds="600"
        memoryStoreEvictionPolicy="LRU"
        statistics="true">
        <cacheEventListenerFactory
            class="net.sf.ehcache.distribution.jgroups.JGroupsCacheReplicatorFactory"
            properties="replicateAsynchronously=true, replicatePuts=true,
            replicateUpdates=true, replicateUpdatesViaCopy=false, replicateRemovals=true" />
</defaultCache>

`

【问题讨论】:

  • 如果不发布 ehcache 配置,很难告诉你错过了什么 :)
  • matt,你去吧,更新了 conf。
  • 我实际上可以看到,使用 ehcache 调试日志级别,在缓存条件查询的主机中接收到插入(放置)消息。但是由于某种原因,查询没有过期。
  • 和休眠配置?
  • 如何插入?您是否有机会通过 JDBC 插入记录而不通过休眠?

标签: java hibernate spring ehcache


【解决方案1】:

恐怕作者有点晚了,但我认为我的回答可能对其他有同样问题的人有用。

您应该记住StandardQueryCacheUpdateTimestampsCache 的工作原理。检查查询缓存时,会将查询缓存的时间与查询中所有表的最后一次更新的时间戳进行比较。如果在缓存查询后更新了任何表,则缓存的结果将被丢弃并使用数据库。每个表的最后一次更新的时间戳存储在UpdateTimestampsCache

在上述配置中,UpdateTimestampsCache 中的值不会复制到集群的其他成员,因此 Hibernate 会查看旧的时间戳并认为缓存的查询是最新的。结果,新插入的记录被忽略。要修复它,只需将 replicateUpdatesViaCopyUpdateTimestampsCache 设置为 true。

【讨论】:

  • 我也有同样的问题。 “replicateUpdatesViaCopy”设置为真。 “永恒”设置为假。查询缓存/更新的时间戳缓存仍然没有失效/复制。还有其他想法吗?
  • @lars 首先,检查复制是否有效。如果您使用 JGroups,请参阅“运行演示程序”here。注意-Djava.net.preferIPv4Stack=true 部分,如果没有它就无法运行演示,您还应该将它添加到您的配置中。其次,您的 Ehcache 配置中的其他内容可能有问题。 Here 是一个对我有用的例子。
  • 明白了,基本错误。我使用“org.hibernate.cache.UpdateTimestampsCache”而不是“org.hibernate.cache.spi.UpdateTimestampsCache”作为时间戳缓存的名称。
【解决方案2】:

参考:Ehcache configuration

请注意,当设置为“true”时,永恒属性会覆盖 timeToLive 和 timeToIdle,因此不会发生过期。

您有 1 个永恒属性设置为真。也许您可以尝试将其设置为 false,看看是否有帮助?

【讨论】:

  • 查询即将过期,然后找到插入的行。我设置了 120 秒的有效期。然后两分钟后查询将获取插入的行。但是,我认为 EHCache 应该更聪明,并发现已插入新记录并使该表上的缓存查询无效......或类似的东西......
猜你喜欢
  • 2015-05-16
  • 1970-01-01
  • 2015-01-09
  • 2013-10-19
  • 1970-01-01
  • 1970-01-01
  • 2020-06-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多