在多线程windows服务应用程序中使用的最佳NHibernate会话管理方法是什么

本文关键字:会话 NHibernate 最佳 管理 管理方 是什么 方法 windows 多线程 服务 应用程序 | 更新日期: 2023-09-27 17:59:22

我有一个使用多线程的windows服务应用程序。我在这个应用程序的数据访问层使用NHibernate。

您对此应用程序中的会话管理有何建议。我读到关于UNHAddins的文章,这是一个好的解决方案吗?

在多线程windows服务应用程序中使用的最佳NHibernate会话管理方法是什么

我使用NHibernate的内置上下文会话。你可以在这里阅读:

http://nhibernate.info/doc/nhibernate-reference/architecture.html#architecture-当前会话

以下是我如何使用的示例:

public class SessionFactory
{
    protected static ISessionFactory sessionFactory;
    private static ILog log = LogManager.GetLogger(typeof(SessionFactory));
    //Several functions omitted for brevity
    public static ISession GetCurrentSession()
    {
        if(!CurrentSessionContext.HasBind(GetSessionFactory()))
            CurrentSessionContext.Bind(GetSessionFactory().OpenSession());
        return GetSessionFactory().GetCurrentSession();
    }
    public static void DisposeCurrentSession()
    {
        ISession currentSession = CurrentSessionContext.Unbind(GetSessionFactory());
        currentSession.Close();
        currentSession.Dispose();
    }
}

除此之外,我的hibernate配置文件中还有以下内容:

<property name="current_session_context_class">thread_static</property>

我从来没有看过未处理的内容,但以下是我用于wcf的内容,我想可能也适用于多线程的通用内容。

这是会话上下文:

namespace Common.Infrastructure.WCF
{
    public class NHibernateWcfSessionContext : ICurrentSessionContext
    {
        private readonly ISessionFactoryImplementor factory;
        public NHibernateWcfSessionContext(ISessionFactoryImplementor factory)
        {
            this.factory = factory;
        }
        /// <summary>
        /// Retrieve the current session for the session factory.
        /// </summary>
        /// <returns></returns>
        public ISession CurrentSession()
        {
            Lazy<ISession> initializer;
            var currentSessionFactoryMap = OperationContext.Current.InstanceContext.Extensions.Find<NHibernateContextManager>().SessionFactoryMaps;
            if (currentSessionFactoryMap == null ||
                !currentSessionFactoryMap.TryGetValue(factory, out initializer))
            {
                return null;
            }
            return initializer.Value;
        }
        /// <summary>
        /// Bind a new sessionInitializer to the context of the sessionFactory.
        /// </summary>
        /// <param name="sessionInitializer"></param>
        /// <param name="sessionFactory"></param>
        public static void Bind(Lazy<ISession> sessionInitializer, ISessionFactory sessionFactory)
        {
            var map = OperationContext.Current.InstanceContext.Extensions.Find<NHibernateContextManager>().SessionFactoryMaps;;
            map[sessionFactory] = sessionInitializer;
        }
        /// <summary>
        /// Unbind the current session of the session factory.
        /// </summary>
        /// <param name="sessionFactory"></param>
        /// <returns></returns>
        public static ISession UnBind(ISessionFactory sessionFactory)
        {
            var map = OperationContext.Current.InstanceContext.Extensions.Find<NHibernateContextManager>().SessionFactoryMaps;
            var sessionInitializer = map[sessionFactory];
            map[sessionFactory] = null;
            if (sessionInitializer == null || !sessionInitializer.IsValueCreated) return null;
            return sessionInitializer.Value;
        }
    }
}

这是上下文管理器:

namespace Common.Infrastructure.WCF
{
    class NHibernateContextManager : IExtension<InstanceContext>
    {
        public IDictionary<ISessionFactory, Lazy<ISession>> SessionFactoryMaps = new Dictionary<ISessionFactory, Lazy<ISession>>();
        public void Attach(InstanceContext owner)
        {
            //We have been attached to the Current operation context from the ServiceInstanceProvider
        }
        public void Detach(InstanceContext owner)
        {
        }
    }
}

编辑:

需要明确的是,正如其他答案所说,线程静态上下文将开箱即用。我在这里的主要优势是1)您可以控制,2)它是一个懒惰的实现,因此如果不必要,您不必为每个线程启动会话。imho,与数据库的连接越少越好。