每个请求实现的NHibernate会话

每个请求实现的NHibernate会话,nhibernate,session,lazy-loading,Nhibernate,Session,Lazy Loading,我想用每个请求的会话实现重建多线程NHibernate应用程序 现在,这个应用程序看起来像是每个会话(每个线程)的会话,并将会话保存到CurrentSessionContext中 但是这个实现带来了加载缓存实体的问题,缓存实体可以从其他会话中更新。所以我想更改这个代码 //main thread using (nHibernateHelper.OpenConnection()){ List<Bar> bars = BarRepository.Instance.GetAll(

我想用每个请求的会话实现重建多线程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
            }
        }
    }
}
//主线程
使用(nHibernateHelper.OpenConnection()){
列表栏=BarRepository.Instance.GetAll();
foreach(条中的条){
//启动线程并执行一些工作,例如通过其他线程运行DoWork(bar)
任务。工厂。开始新建(道工、酒吧);
}
}
//其他线程
空心销钉(钢筋){
使用(nHibernateHelper.OpenConnection()){
foreach(酒吧里的Foo-Foo.傻瓜){
if(foo.SomeState==PredifinedState){
//调用许多其他函数
}
}
}
}

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

在NHibernate中,会话显然不是线程安全的(请参阅),因此如果不锁定,您无法在多个线程之间共享它们

如果你的问题没有更多的背景,就很难提供一个精确的解决方案,但是下面这样的东西会有帮助吗

//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();
                }                
        }
    }
}
//主线程
列表栏=BarRepository.Instance.GetAll();
foreach(条中的条){
//启动线程并执行一些工作,例如通过其他线程运行DoWork(bar)
Task.Factory.StartNew(DoWork、bar、NHibernateHelper.CurrentSession());
}
无效定位销(条形、ISession会话){
foreach(酒吧里的Foo-Foo.傻瓜){
if(foo.SomeState==PredifinedState){
//调用许多其他函数
锁(会话)
{
使用(var-tran=session.BeginTransaction())
{
session.Save(foo);
trans.Commit();
}                
}
}
}

Task.Factory.StartNew(DoWork、bar、NHibernateHelper.CurrentSession());
。您的db server将开始执行此操作。但是,从技术上讲,这是对问题的正确回答。抱歉,我指定了我使用的会话对象,因此我们不需要将会话对象传递给其他线程。主要思想是更改每个应用程序的会话管理策略(现在看起来是这样的)每个工作单元的会话。我知道如何通过IDisposable类和将上下文会话更改为CallSessionContext来实现这一点。但是:对于长foreach循环,我需要做什么?我使用ThreadStaticSessionContext上下文会话,而nHibernateHelper.OpenConnection()是IDisposable返回此会话(或使用绑定/取消绑定创建新会话)来自CurrentSessionContext。