在集成两个子系统时,我们被迫使用多个SessionFactory实例,这些实例在与我们的Hibernate二级缓存(Terracotta EhCache)进行交互时会导致问题.特别:
for(CacheManager cm : CacheManager.ALL_CACHE_MANAGERS){ LOGGER.log(Level.DEBUG,"In cm " + cm.getName()); for(String cn : cm.getCacheNames()){ LOGGER.log(Level.DEBUG,"I have a cache called " + cn); LOGGER.log(Level.DEBUG,"it's status is " + ms.getCache(cn).getStatus()); } } try{ myCollection.size(); }catch(IllegalStateException ise){ LOGGER.log(Level.FATAL,ise); //Triggered }
调试打印输出显示缓存“Foo”的STATUS_ALIVE,但调用size()会抛出IllegalStateException:
java.lang.IllegalStateException: The Foo Cache is not alive.
目前,SessionFactories都配置为使用SingletonEhCacheRegionFactory.如果我切换SessionFactories以使用EhCacheRegionFactory(非单例),缓存行为的后果是什么(特别是在Web App上下文中)?
解决方法
EhCache将确保SingletonEhCacheRegionFactory的所有实例在内部使用相同的实际CacheManager,无论您创建多少个SingletonEhCacheRegionFactory实例,使其成为Singleton设计模式的粗体版本.
另一方面,平原EhCacheRegionFactory每次都会获得一个新的CacheManager.
如果Spring中有两个Hibernate会话工厂,每个都使用自己的SingletonEhCacheRegionFactory实例,那么实际上它们最终会共享很多缓存状态,这可能是您的问题.
这并不是一个很好的搭配,因为单身人士应该由容器来管理.如果您使用EhCacheRegionFactory,那么您可能会获得更多可预测的结果.我建议你去看看你怎么去.