Сессия NHibernate для каждого запроса - PullRequest
0 голосов
/ 12 октября 2011

Я хочу перестроить многопоточное приложение 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
            }
        }
    }
}

Основной вопрос: как изменить этот код, чтобы закрыть Session перед запуском другого потока с помощью LazyLoading (Bar содержит отношения к другим объектам, и эти отношения используются воработа), а до вызова других функций из оператора foreach в функции DoWork?

1 Ответ

0 голосов
/ 13 октября 2011

В NHibernate сеансы явно не являются поточно-ориентированными (см. 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();
                }                
        }
    }
}
...