代码之家  ›  专栏  ›  技术社区  ›  SHSE

在不同会话之间共享第一级缓存?

  •  2
  • SHSE  · 技术社区  · 15 年前

    不同的nhibernate会话是否可以共享一个一级缓存?我试过用拦截器和监听器来实现它。除session.evict()外,所有功能都正常。

    public class SharedCache :
        EmptyInterceptor,
        IFlushEntityEventListener,
        ILoadEventListener,
        IEvictEventListener,
        ISharedCache {
        [ThreadStatic]
        private readonly Dictionary<string, Dictionary<object, object>> cache;
    
        private ISessionFactory factory;
    
        public SharedCache() {
            this.cache = new Dictionary<string, Dictionary<object, object>>();
        }
    
        public override object Instantiate(string clazz, EntityMode entityMode, object id) {
            var entityCache = this.GetCache(clazz);
            if (entityCache.ContainsKey(id))
                return entityCache[id];
    
            var entity = Activator.CreateInstance(Type.GetType(clazz));
            this.factory.GetClassMetadata(clazz).SetIdentifier(entity, id, entityMode);
            return entity;
        }
    
        private Dictionary<object, object> GetCache(string clazz) {
            if (!cache.ContainsKey(clazz))
                cache.Add(clazz, new Dictionary<object, object>());
    
            return cache[clazz];
        }
    
        public void Configure(Configuration config) {
            config.SetInterceptor(this);
            config.SetListener(ListenerType.FlushEntity, this);
            config.SetListener(ListenerType.Load, this);
            config.SetListener(ListenerType.Evict, this);
        }
    
        public void Initialize(ISessionFactory sessionFactory) {
            this.factory = sessionFactory;
        }
    
        public void OnFlushEntity(FlushEntityEvent ev) {
            var entry = ev.EntityEntry;
    
            var entityCache = this.GetCache(ev.EntityEntry.EntityName);
    
            if (entry.Status == Status.Deleted) {
                entityCache.Remove(entry.Id);
                return;
            }
    
            if (!entry.ExistsInDatabase && !entityCache.ContainsKey(entry.Id))
                entityCache.Add(entry.Id, ev.Entity);
        }
    
    
        public void OnLoad(LoadEvent ev, LoadType loadType) {
            var entityCache = this.GetCache(ev.EntityClassName);
    
            if (entityCache.ContainsKey(ev.EntityId))
                ev.Result = entityCache[ev.EntityId];
        }
    
        public void OnEvict(EvictEvent ev) {
            var entityName = ev.Session.GetEntityName(ev.Entity);
            var entityCache = this.GetCache(entityName);
            var id = ev.Session.GetIdentifier(ev.Entity);
    
            entityCache.Remove(id);
        }
    
    }
    
    1 回复  |  直到 14 年前
        1
  •  2
  •   Richard    15 年前

    如果要共享缓存,则不能共享1第一级或会话缓存。应使用会话工厂附带的第二级缓存。- see the docs

    您必须小心,因为如果数据在非特定会话(如通过触发器或其他客户端)之外更改,缓存将不会失效,或者在其他计算机上运行的代码的其他实例。