【问题标题】:NHibernate Multithreaded Session ManagementNHibernate 多线程会话管理
【发布时间】:2011-12-07 23:40:51
【问题描述】:

我遇到的情况涉及多个线程同时使用从 Web 源抓取的数据填充数据库。刮板将定期运行以从各种来源收集新数据。

我是使用 NHibernate 的新手,不完全确定如何最好地管理会话。

每个工人的工作示例:

  • 从 Web 源中抓取实体 A
  • 抓取与 A 相关的每个实体 B,并记录 A 有另一个 B(即一个 A 有多个 B,一个 B 有一个 A)

要持久化每个 B,会话需要对 A 的引用来创建 B,然后 A 需要将 B 添加到其子列表中。然后 A 和 B 都被持久化。

这种 A-B 子-父情况有一个层次结构,即 A 有很多 B,B 有很多 C... 在叶级别,A 有数千个叶子,所以不切实际(?)保持会话在这条链中一直处于打开状态。

另一种方法是记录链中每个父级的标识符(可以独立于会话存储),并在每次需要创建子级时通过此 id 加载到父级中。

我也明白ISession 是单线程的,所以我每个线程至少需要一个会话,但除此之外我真的不确定最好的方法吗?

任何想法表示赞赏,目前有点困惑!

【问题讨论】:

    标签: database hibernate nhibernate web-scraping single-user


    【解决方案1】:

    为每个线程创建一个会话并使用session.Load<>() 来维护关联,而无需每次都加载对象。

    var data = GetDataForBs();
    
    using (var session = OpenSession())
    using (var tx = session.BeginTransaction())
    {
        foreach (var item in data)
        {
            B = ... // create B
            B.A = session.Load<A>(data.A_Id); // Creates a proxy without loading A to maintain the association
            session.save(B);
        }
        tx.Commit();
    }
    

    如果每个实体都独立存在(不需要级联),您可以使用 StatelessSession 来加快速度

    【讨论】:

    • StatelessSession 适合我的情况,感谢您的建议。此外,多久开始和提交事务是一个好主意,例如我应该提交每个单独的插入还是分组多个插入?
    • 如果你需要速度,那么分组会更好,如果你不想丢失一些插入以防提交抛出(例如你不能重复)然后提交每个插入
    猜你喜欢
    • 1970-01-01
    • 2010-09-19
    • 1970-01-01
    • 1970-01-01
    • 2010-11-15
    • 1970-01-01
    • 2010-10-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多