【发布时间】:2017-01-30 14:58:18
【问题描述】:
我有一个 App Engine 项目,它使用 EclipseLink 作为 JPA 持久性管理器,将数据持久保存在 Cloud SQL 实例中。
由于 App Engine(多实例环境)的性质,我们对如何在实例之间同步 JPA 缓存有些担忧。
每个 JPA 实例在单个 App Engine 实例中运行,因此不使用 App Engine 的 Memcache 服务(否则,EclipseLink 不“知道” App Engine memcache 是什么或如何使用它)
这是一个简单的场景示例:
- Instance A read object 1: value="A"
- Instance B read object 1: value="A"
- Instance A write object 1: value="B"
- JPA cache of Instance A is evicted due to write operation
- Instance A read object 1: value="B" (the value is retrieved from the database because cache has been evicted after write operation)
- Instance B read object 1: value="A" (no write operation has been performed, the cache is still valid so the value has not been updated)
四处搜索这种行为,我发现了不同的文章,它们都在谈论这个 [1] [2] [3] [4]。
我引用:
除非数据库由其他应用程序直接修改,或由 集群环境中其他服务器上的相同应用程序
由于 App Engine 的本质,为此我们可以将其视为“集群环境中的其他服务器”,因此情况似乎就是这样。
当然,关于如何处理这个问题的正确方法应该是为 JPA 构建一个缓存层,该缓存层构建在 App Engine 内存缓存服务之上,但根据我的搜索,我了解到 EclipseLink 不允许开发自定义缓存层。 我可以构建一些可以在 EclipseLink 和 App Engine 内存缓存之间架起桥梁的东西,但是如果有正确的“钩子”来说明如何做,我找不到任何参考。
从文档中关于如何处理这个问题的建议很少:
禁用共享缓存:由于失去应用程序性能,这不是一个合适的选项
使用分布式缓存(例如带有 Oracle Coherence 的 Oracle TopLink Grid): 我想使用 App Engine 内存缓存服务,但据我了解,没有我们可以使用的 EclipseLink“挂钩”
使用缓存协调(同步缓存,如本例所述) 提供的方法似乎不适用于 App Engine 环境
是否有关于如何正确处理此缓存方案的已知解决方案? 这里的场景很清楚,当在实例内部进行写操作时,所有现有的 JPA 缓存也需要“通知”以驱逐自己的缓存。
[1]https://wiki.eclipse.org/EclipseLink/Examples/JPA/CacheCoordination
[2]http://www.eclipse.org/eclipselink/documentation/2.5/concepts/cache011.htm
[3]https://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Basic_JPA_Development/Caching/Coordination
[4]https://wiki.eclipse.org/EclipseLink/Examples/JPA/Caching#Caching_in_Clustered_Environments
【问题讨论】:
标签: java google-app-engine jpa caching eclipselink