NHibernate SessionFactory线程安全问题

时间:2011-09-09 09:55:43

标签: c# nhibernate thread-safety sessionfactory

所以这就是问题所在。我有一个公共类库,包含所有存储库,域和映射文件,因此库可以在其他Web beased应用程序中重用。现在,在这个类库中,有一段代码允许自己创建一个在其存储库中使用的会话工厂。代码看起来像这样。

        private static ISessionFactory sessionFactory;
        private static Configuration configuration;

        public static Configuration Configuration()
        {
            if (configuration == null)
            {
                configuration = new Configuration().Configure();
            }
            return configuration;
        }

        private static ISessionFactory SessionFactory
        {
            get
            {
                if (sessionFactory == null)
                {
                    sessionFactory = Configuration().BuildSessionFactory();
                }
                return sessionFactory;
            }
        }

        public static ISession GetCurrentSession()
        {
            if (!CurrentSessionContext.HasBind(SessionFactory))
            {
                CurrentSessionContext.Bind(SessionFactory.OpenSession());
            }
            return SessionFactory.GetCurrentSession();
        }

因此存储库调用GetCurrentSession()方法来获取ISession。现在这工作正常,但我担心它可能不是线程安全的。任何人都可以帮助我一种方法,帮助我使线程安全。

注意事项:

我已经考虑过在启动事件的web应用程序的global.asax中配置和构建SessionFactory,但问题是所讨论的公共类库在20个不同的应用程序中使用,所以这意味着要去所有的应用程序并在我执行此操作之前更新global.asax文件我想在那里提出问题,看看是否还有其他方法可以解决这个问题。因此,公共类库可以配置其SessionFactory本身,但仍然是线程安全的。

感谢您阅读这个大问题。将提供任何帮助。

4 个答案:

答案 0 :(得分:7)

会话工厂是线程安全的,会话不是。建立会话工厂需要得到保护:

    private static object lockObject = new object();

    private static ISessionFactory SessionFactory
    {
        get
        {
            lock (lockObject)
            {
                if (sessionFactory == null)
                {
                    sessionFactory = Configuration().BuildSessionFactory();
                }
                return sessionFactory;
            }
        }
    }

会话工厂是在线程第一次请求会话时创建的。这需要是线程安全的,以避免多次创建会话工厂。

会话工厂创建会话是线程安全的,因此您无需担心。

答案 1 :(得分:0)

通过设计,会话在NHibernate中不是线程安全的。所以只要你有只有一个线程使用的会话就应该没问题。 只要每个线程有一个单独的NHibernate会话,就可以为多个线程安装一个NHibernate SessionFactory

了解更多信息,请查看以下链接:

https://forum.hibernate.org/viewtopic.php?p=2373236&sid=db537baa5a57e3968abdda5cceec2a24

答案 2 :(得分:0)

我建议为每个请求使用一个会话,如下所示:

public ISession GetCurrentSession()
{
        HttpContext context = HttpContext.Current;

        var currentSession = context.Items["session"] as ISession;

        if( currentSession is null )
        {
             currentSession = SessionFactory.GetCurrentSession()
             context.Items["session"] = currentSession;
        }

        return currentSession;
}

答案 3 :(得分:0)

根据Stefan Steinegger的评论,我认为在锁定之前立即添加空检查会更有效,这样,即使sessionFactory已经初始化,也不需要每次都锁定。

    if (/firefox/i.test(navigator.userAgent)){
   window.oldGetComputedStyle = window.getComputedStyle;
   window.getComputedStyle = function (element, pseudoElt) {
      var t = window.oldGetComputedStyle(element, pseudoElt);
      if (t === null) {
         return {
            getPropertyValue: function(){}
         };
      } else{
         return t;
      }
   };
}