我们有一个包含 n 个客户端(目前为 55 个)的系统,其中每个客户端都有自己的数据库,所有这些数据库都具有完全相同的模式。我们正在运行由分布式 ehcache 支持的休眠 3.6.1。这已通过 SessionFactoryService 使用每个数据库的 SessionFactory 实现,该 SessionFactoryService 在运行时“懒惰地”为每个 jvm 的每个客户端创建一个 SessionFactory(存储在 HashMap 中),因此我们正在运行一组应用程序管理的 SessionFactories。有一个基本的休眠配置文件,其余设置在创建时以编程方式完成。我们的存储库(或者更常见的 DAO)可以通过 SessionFactoryService 访问 SessionFactory。我们充分利用了由分布式 SingltonEhcacheRegionFactory 支持的休眠二级缓存。因为我们在每个 jvm 运行 n 个 SessionFactories,所以我们不想要一个 NON SingltonEhacheRegionFactory(即每个 SessionFactory 有一个 CacheManager),因为在尝试保持缓存之间的同步时,SessionFactories 之间会有太多的 jvm 间通信。所以我们想要的只是跨服务器的通信,而不是服务器内的通信,这是通过 SingltonEhcacheRegionFactory 实现的。
现在,这里是乐趣的开始。使用上述设置,将存在缓存冲突,因为无法保证唯一键作为数据库模式,因此支持它们的实体对象在 SessionFactories 中是相同的。为了使它们独一无二,我们通过上面的编程配置步骤将字段 hibernate.cache.region_pre-fix 设置为每个 SessionFactory 的唯一值。这满足了 Hibernate 对二级缓存的看法,但底层的单例 ehcache 现在存在问题。它找不到正确的配置,因为 ehache.xml 配置文件中指定的配置在缓存名称上没有缓存前缀(也不能,因为每个前缀的每个缓存配置都必须有一个重复条目,其中有n个)。这会导致以下错误:
10:37:38,389 WARN AbstractEhcacheRegionFactory:201 - 在 Hibernate 配置中找不到 TransactionManagerLookup,XA 缓存将参与两阶段提交!10:37:39,675 WARN AbstractEhcacheRegionFactory:143 - 找不到名为 [some_prefix.adc] 的缓存的特定 ehcache 配置;使用默认值。10:37:40,328 WARN AbstractEhcacheRegionFactory:143 - 找不到名为 [some_prefix.org.hibernate.cache.UpdateTimestampsCache] 的缓存的特定 ehcache 配置;使用默认值。10:37:40,331 WARN AbstractEhcacheRegionFactory:143 - 找不到名为 [some_prefix.org.hibernate.cache.StandardQueryCache] 的缓存的特定 ehcache 配置;使用默认值。
那么问题来了,我们如何才能在每个 jvm 环境中使用分布式单例 ehcache 来完成多个 SessionFactory?有没有办法将 ehcache 配置为区域前缀感知?我们实施的解决方案充其量只是hacky。我们已经实现了自己的 hibernate.cache.region.factory_class,它扩展了 SingltonEhcacheRegionFactory(并删除了 hibernate 缓存区域前缀配置)。我们的实现所做的只是拦截对底层 Ehcache 的方法调用,并为所有用于缓存操作的键附加一个前缀,从而防止缓存冲突。我们想要一个更“开箱即用”的解决方案,出于显而易见的原因,尽管它有效,但我们实施的方案并不理想。我已经阅读了我可能找到的关于此事的所有内容,但没有 t 找到了一个解决方案,该解决方案使用分布式二级缓存使用相同的模式(最重要的是)处理多个 SessionFactories。任何想法、解决方案或建议将不胜感激。如果有人有解决需求的好方法,我什至对完全不同的设计持开放态度。提前致谢!