我想用每个请求实现的会话重建多线程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功能?
答案 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();
}
}
}
}