对象缓存和查询缓存是相互独立的,尽管它们可以影响彼此的状态。
对象缓存
扩展对象图时访问对象缓存(正如您正确注意到的那样)。但是对象缓存的同步不只是更新缓存,还会传播到ObjectContexts,导致内存中对象图的刷新。虽然这听起来很棒并且超级自动化,但从经验来看,它在桌面应用程序中最有用,当您拥有与单个用户相关的有限对象图时。在集群的多用户 Web 应用程序中,同步对象缓存更麻烦,而不是帮助。它会产生大量网络流量,迫使您的实例消耗 CPU 来处理他们并不真正关心的事件,最后,在您最不期望的时候从底层更新您的对象。所以我通常会关闭对象缓存同步,而纯粹依靠集群查询缓存来处理同步。
查询缓存
这是一个示例项目,演示了使用集群的查询缓存。它使用 Cayenne 4.0,EHCache 作为缓存提供者,ActiveMQ/JMS 用于跨实例事件。
查询缓存的工作方式是缓存与给定查询匹配的对象列表,如果查询包含预取,则包括预取的相关对象。要充分利用查询缓存,您可能需要稍微改变一下编码风格。您无需在实例变量中存储对查询结果列表的长期引用(本质上是进行自己的缓存),而是在需要此类列表时随时创建并运行查询(使用适当的缓存设置),并让 Cayenne 决定该列表是否应该从缓存中返回或从数据库中重新获取。
下一步是根据您使用的提供程序来配置您的缓存,以指定其默认过期策略(每个缓存组)。例如一个示例 EHCache 配置。
最后,您可以添加集群和事件驱动的缓存刷新,这可以通过 API 调用显式完成,或者在提交某些实体时隐式完成(仅从 Cayenne 3.1 开始可用)。
查询缓存刷新非常便宜。通过网络发送的唯一内容是“缓存组”的名称,在接收端,一堆列表立即被懒惰地失效。它还可以产生更清晰的代码。
如果您主要依赖查询缓存,则不需要“关闭”对象缓存本身。对象缓存是 Cayenne 的一个组成部分,是许多操作(更新、关系处理)所必需的。它将在您运行查询时自动更新。您通常需要做的是关闭自动对象刷新。通过不启用对象缓存集群,您已经避免了跨 JVM 同步。此外,您可以使用此建议禁用同一 VM 内的跨 ObjectContext 同步。
卡宴版本
我强烈建议至少升级到 Cayenne 3.1(甚至升级到 4.0.M2)。除了其他优点之外,缓存机制比 3.0 更成熟。它将使您配置 Cayenne 和集成外部缓存提供程序的体验变得更加轻松。