NHibernate SessionFactory线程安全问题
本文关键字:问题 安全 线程 SessionFactory NHibernate | 更新日期: 2023-09-27 18:08:09
问题就在这里。我有一个公共类库,它包含所有的存储库、域和映射文件,因此该库可以在其他基于web的应用程序中重用。现在,在这个类库中有一段代码,它允许自己创建一个会话工厂,以便在其存储库中使用。代码看起来像这样:
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()方法来获取session。现在这工作得很好,但我担心它可能不是线程安全的。谁能告诉我一个方法,使它线程安全?
注意事项:
我考虑过在全局中配置和构建SessionFactory。一个web应用程序的启动事件,但这样做的问题是,有问题的公共类库在20个不同的应用程序中使用,所以这将意味着要去所有的应用程序和更新全局。asax文件现在,在我这样做之前,我想把问题放在那里,看看是否有任何其他的方法,我可以做到这一点。这样,公共类库就可以自己配置它的SessionFactory,并且仍然是线程安全的。
谢谢你阅读这个大问题。将感谢任何帮助。
会话工厂是线程安全的,而会话不是。构建会话工厂需要被保护:
private static object lockObject = new object();
private static ISessionFactory SessionFactory
{
get
{
lock (lockObject)
{
if (sessionFactory == null)
{
sessionFactory = Configuration().BuildSessionFactory();
}
return sessionFactory;
}
}
}
在线程第一次请求会话时创建会话工厂。这需要是线程安全的,以避免多次创建会话工厂。
通过会话工厂创建会话是线程安全的,所以您不需要担心这个问题。
会话在NHibernate中不是线程安全的。因此,只要您有一个仅由一个线程使用的会话,它应该是可以的。你可以为多个线程使用一个NHibernate SessionFactory,只要你为每个线程使用一个单独的NHibernate会话
更多信息请看下面的链接:
https://forum.hibernate.org/viewtopic.php?p=2373236& sid = db537baa5a57e3968abdda5cceec2a24
我建议为每个请求使用一个会话,像这样:
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;
}
根据Stefan Steinegger的评论,我认为在锁定之前立即添加null检查会更有效,这样如果sessionFactory已经初始化,您就不需要每次都锁定。
private static object lockObject = new object();
private static ISessionFactory SessionFactory
{
get
{
if (sessionFactory != null)
{
return sessionFactory;
}
lock (lockObject)
{
if (sessionFactory == null)
{
sessionFactory = Configuration().BuildSessionFactory();
}
return sessionFactory;
}
}
}