3

我有一个使用 NHibernate 映射并缓存在二级缓存 (memcached) 中的类“公司”。我们的团队最近为此类添加了一个新的 bool 属性,该属性将存储在数据库中。

在我们的开发环境中一切正常,但是一旦我们部署到我们的暂存环境(共享实时数据库),我们就开始收到以下错误:

System.IndexOutOfRangeException: Index was outside the bounds of the array.
at (Object , Object[] , SetterCallback )
at NHibernate.Tuple.Entity.PocoEntityTuplizer.SetPropertyValuesWithOptimizer(Object entity, Object[] values)
at NHibernate.Tuple.Entity.PocoEntityTuplizer.SetPropertyValues(Object entity, Object[] values)
at NHibernate.Persister.Entity.AbstractEntityPersister.SetPropertyValues(Object obj, Object[] values, EntityMode entityMode)
at NHibernate.Cache.Entry.CacheEntry.Assemble(Object[] values, Object result, Object id, IEntityPersister persister, IInterceptor interceptor, ISessionImplementor session)
at NHibernate.Cache.Entry.CacheEntry.Assemble(Object instance, Object id, IEntityPersister persister, IInterceptor interceptor, ISessionImplementor session)
at NHibernate.Event.Default.DefaultLoadEventListener.AssembleCacheEntry(CacheEntry entry, Object id, IEntityPersister persister, LoadEvent event)
at NHibernate.Event.Default.DefaultLoadEventListener.LoadFromSecondLevelCache(LoadEvent event, IEntityPersister persister, LoadType options)
at NHibernate.Event.Default.DefaultLoadEventListener.DoLoad(LoadEvent event, IEntityPersister persister, EntityKey keyToLoad, LoadType options)

我最好的猜测是 NHibernate 不能将旧的缓存条目(没有新属性)反序列化到新的 Company 对象中。我相信我确认了这一点,因为我在我们的暂存环境中禁用了二级缓存并且 ISE 停止了。

所以我想我的问题是,如果 NHibernate 不能反序列化缓存条目而不是冒泡异常,我们如何强制它进入数据库?有没有其他人遇到过这个问题?

我认为现在,我们将不得不在关闭二级缓存的情况下进行部署,重新启动 memcached 服务器,然后重新启用二级缓存。然而,这种解决方案并不理想。如果有人有更好的建议,我将不胜感激。

4

3 回答 3

0

作为对任何感兴趣的人的更新,我遵循了我的帖子中概述的步骤:

[...] 我们将不得不在关闭二级缓存的情况下进行部署,重新启动 memcached 服务器,然后重新启用二级缓存。

...一切正常。它比我们的正常部署要复杂一些,但我们没有任何错误。

于 2012-06-04T14:30:10.907 回答
0

做所有不必要的事情——关闭二级缓存并重新启动等等。我认为您真正想要的只是使缓存中的项目无效以使 nhibernate 进入数据库。

如果找到与 memcached 相关的 gem - 您可以通过从 telnet 接口刷新整个缓存来使其无效。

telnet SomeServerInCluster 11211
flush_all

并且您已经通过重新启动所有 memcached 机器完成了您想要完成的任务。

http://www.lzone.de/articles/memcached.htm

于 2013-07-26T17:58:10.633 回答
0

你们在使用缓存区域前缀吗?我已经实现的是,每当我们有核心定义更改时,我们都会写入不同的缓存区域前缀。这类似于刷新缓存区域。

好处是您不会遇到新定义与缓存的旧定义不匹配的问题。

不利的一面是,这会降低性能,因为现在需要重建缓存。

为了降低性能,您始终可以包括(作为部署过程的一部分)一个缓存预热例程,该例程在您看到应用程序的任何大量流量之前启动缓存。

希望这可以帮助。

于 2013-11-19T21:16:15.500 回答