每个请求实现的NHibernate会话

时间:2011-10-12 11:25:36

标签: nhibernate session lazy-loading

我想用每个请求实现的会话重建多线程NHibernate应用程序。

现在,此应用程序看起来像每个会话的会话(每个线程),并将会话保存到CurrentSessionContext中。

但是这种实现会带来加载缓存实体的问题,这些实体可以从其他会话中更新。所以我想改变这段代码

//main thread 
using (nHibernateHelper.OpenConnection()){
    List<Bar> bars = BarRepository.Instance.GetAll();
    foreach (Bar bar in bars){
        //start thread and do some work, for example run DoWork(bar); by other thread
        Task.Factory.StartNew(DoWork, bar);
    }
}

//other thread
void DoWork(Bar bar){
    using (nHibernateHelper.OpenConnection()){
        foreach (Foo foo in bar.FooList){
            if (foo.SomeState == PredifinedState) {
                //call many other functions
            }
        }
    }
}

主要问题是:如何更改此代码,在使用LazyLoading启动其他线程之前关闭Session(Bar包含与其他对象的关系,此关系在线程工作期间使用),并在调用foreach语句中的其他函数之前DoWork功能?

1 个答案:

答案 0 :(得分:0)

在NHibernate中,Sessions明显不是线程安全的(参见http://nhibernate.info/doc/nh/en/index.html#transactions),所以你不能在没有锁定的情况下在多个线程之间共享它们。

如果没有更多的问题背景,很难提供一个确切的解决方案,但下面的内容会有所帮助吗?

//main thread 

    List<Bar> bars = BarRepository.Instance.GetAll();
    foreach (Bar bar in bars){
        //start thread and do some work, for example run DoWork(bar); by other thread
        Task.Factory.StartNew(DoWork, bar, NHibernateHelper.CurrentSession());
    }

void DoWork(Bar bar, ISession session){
    foreach (Foo foo in bar.FooList){
        if (foo.SomeState == PredifinedState) {
            //call many other functions
            lock (session)
            {
                using (var tran = session.BeginTransaction())
                {
                    session.Save(foo);
                    tran.Commit();
                }                
        }
    }
}