【问题标题】:Nhibernate and session pooling休眠和会话池
【发布时间】:2017-02-14 14:48:45
【问题描述】:

我正在做一个项目,应该每 1 秒向表中插入一条新消息。在 EntityFramework 中,有一种叫做连接池的东西,它使它成为保持上下文生命周期尽可能短的更好选择。我们处置上下文。这是否适用于 Nhibernate 会话?

ISessionFactory sf = cfg.BuildSessionFactory();
ISession session = sf.OpenSession();
While(true)
{
//.......
    using (var tran = session.BeginTransaction())
    {
        session.SaveOrUpdate(msg);
        tran.Commit();                           
    }
    Thread.Sleep(1000);
}

或者

ISessionFactory sf = cfg.BuildSessionFactory();
While(true)
{
//.......
    using(var session = sf.OpenSession())
    {
     using (var tran = session.BeginTransaction())
     {
         session.SaveOrUpdate(msg);
         tran.Commit();                           
     }
     Thread.Sleep(1000);
    }
}

似乎都可以,但我应该使用哪一个?

【问题讨论】:

标签: c# entity-framework session nhibernate


【解决方案1】:

好吧,如果我决定只回答你的问题:

second 代码块更合适。实际上,连接池与 NHibernate 无关。这是底层 RDBMS 的行为。

在 NHibernate 中,创建 SessionFactory 的成本很高,并且应该在应用程序生命周期内只执行一次(理想情况下是在启动时)。创建ISession 并不昂贵。建议您的会话应尽可能短。

不仅仅是回答:

除了短暂的离开会话之外,您还应该考虑实现UnitOfWork(“会话每次会话”,即正确使用事务和会话)以提高一级缓存和批处理的好处。

一级缓存是每个会话。如果您在新会话上运行每个数据库调用,您实际上并没有获得缓存优势。

批处理也是如此。批处理是根据您处理事务的方式完成的。调用tran.Commit();nhSession.FlushModenhSession.SetBatchSize 等其他属性一起发挥重要作用。参考this文章。
要实现批处理,我建议您改进 first 代码块,而不是在 using 块中提交事务,而是在循环的每 100 次(或 10 或 500 次任何适合您的)迭代中执行一次。

请参阅thisthis 问题。

请参阅@Fran 在 cmets 中所说的 this 答案。

【讨论】:

  • 谢谢!这对我有很大帮助。但就我而言,源数据是从物理设备获取的,每秒生成一个数据。因此,如果我像你说的那样进行批处理,会话需要在提交和处理之前存活 500 秒,这可能违反第一条规则。
  • 同意;无论如何,批处理在这种情况下对您没有帮助。
猜你喜欢
  • 2014-11-14
  • 2012-06-02
  • 2014-11-17
  • 1970-01-01
  • 2015-03-18
  • 2018-09-27
  • 2013-09-14
相关资源
最近更新 更多