c# - 在不同 session 之间共享一级缓存?

标签 c# .net nhibernate session caching

不同的 NHibernate session 是否可以共享一个一级缓存?我尝试使用拦截器和监听器来实现它。除了 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);
    }

}

最佳答案

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

您必须小心,因为如果数据在 nhibernate session 之外发生更改,例如通过触发器或其他客户端 - 或者您的代码在另一台机器上运行的另一个实例,则缓存不会失效

关于c# - 在不同 session 之间共享一级缓存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1444791/

相关文章:

c# - 如何维护和返回任务的进度?

c# - 如何从 NHibernate 调用没有结果的存储过程?

c# - NHibernate 查询使用 Criteria-api 返回未映射的对象

c# - ASP.NET 在 If 语句的 .aspx 中使用 Bind/Eval

c# - 将数组转换为多行字符串的最快方法

c# - 如何合并拆分为 2 个具有奇数和偶数索引的数组?

.net - 如何创建共享方法的扩展

c# - 如何保护 OAuth key 不被用户反编译我的项目?

c# - 在 .NET 中使用 MEF 仅获取必要的插件

nhibernate - 在 Concat 投影中使用 Cast Projection