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

发布于 2024-11-15 18:09:55 字数 116 浏览 3 评论 0原文

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

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

I have a windows service application that work with multithread. I use NHibernate in data access layer of this application.

What is your suggestion for session management in this application. I read about UNHAddins, Is it a good solution?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

烂人 2024-11-22 18:09:55

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

http://nhibernate.info /doc/nhibernate-reference/architecture.html#architecture-current-session

这是我如何使用它的示例:

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();
    }
}

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

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

I use NHibernate's built in contextual sessions. You can read about them here:

http://nhibernate.info/doc/nhibernate-reference/architecture.html#architecture-current-session

Here is an example of how I use this:

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();
    }
}

In addition to this I have the following in my hibernate config file:

<property name="current_session_context_class">thread_static</property>
飞烟轻若梦 2024-11-22 18:09:55

我从来没有看过 unhaddins,但这是我用于 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)它是一个惰性实现,所以如果没有必要,你不必为每个线程启动一个会话。恕我直言,与数据库的连接越少越好。

i've not ever looked at the unhaddins, but here's what i use for wcf stuff, should probably work for multithreaded general stuff too i imagine.

this is the session context:

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;
        }
    }
}

this is the context manager :

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)
        {
        }
    }
}

Edit:

to be clear, as the other answer states, the thread static context will work out of the box. the main advantage of what i have here is 1) you get to be in control, and 2) its a lazy implementation, so you don't have to start a session for each thread if its not necessary. less connection to the db is always better, imho.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文