在NHibernate中同时打开多个会话

时间:2009-10-16 19:52:48

标签: multithreading nhibernate

我终于弄清楚我的代码有什么问题,但我不确定如何修复它。我有一些后台进程在一个单独的线程上运行,执行一些数据库维护任务。这是一个正在发生的事情的例子:

//Both processes share the same instance of ISessionFactory
//but open separate ISessions

//This is running on it's own thread
public void ShortRunningTask()
{
    using(var session = _sessionFactory.OpenSession())
    {
        //Do something quickly here
        session.Update(myrecord);
    }
}

//This is running on another thread
public void LongRunningTask()
{
    using(var session = _sessionFactory.OpenSession())
    {
        //Do something long here
    }
}

假设我首先开始LongRunningTask。当它正在运行时,我在另一个线程上启动ShortRunningTaskShortRunningTask完成并关闭其会话。一旦LongRunningTask完成,它会尝试对它创建的会话执行某些操作,但会抛出错误,说会话已经关闭。

显然正在发生的事情是,ISessionFactory.OpenSession()并未表示我已经打开了2个单独的会话。关闭在ShortRunningTask中打开的会话也会关闭LongRunningTask中的会话如何解决此问题?请帮忙!

谢谢!


更新

显然每个人都认为我的修复是完全错误的。所以这是我正在使用的配置:

_sessionFactory = Fluently.Configure()
                  .Database(
                  FluentNHibernate.Cfg.Db.MsSqlConfiguration.MsSql2008
                  .ConnectionString(db => db.Is(
WikipediaMaze.Core.Properties.Settings.Default.WikipediaMazeConnection)))
                  .Mappings(m => m.FluentMappings.AddFromAssemblyOf<IRepository>())
                  .BuildSessionFactory();

我没有在xml文件中进行配置。应该有吗?我错过了什么这是打开多个会话失败的另一个例子:

public void OpenMultipleSessionsTest()
{
    using(var session1 = _sessionFactory.OpenSession())
    {
        var user = session1.Get<Users>().ById(1);
        user.Name = "New Name";

        using(var session2 = _sessionFactory.OpenSession())
        {
            //Do some other operation here.
        }

        session1.Update(user);
        session1.Flush(); // Throws error 'ISession already closed!'
    }
}

1 个答案:

答案 0 :(得分:-2)

我想出了如何解决这个问题。我将SessionFactory设置为单例,使其成为[ThreadStatic],如下所示:

[ThreadStatic]
private ISessionFactory _sessionFactory;

[ThreadStatic]
private bool _isInitialized;

public ISessionFactory SessionFactory
{
    get
    {
        if(!_isInitialized)
        {
            //Initialize the session factory here
        }
    }
}

问题的症结在于,在同一个ISessionFactory的不同线程上创建会话是有问题的。 ISessionFactory不喜欢同时打开多个ISession。关闭一个,自动关闭任何其他打开的。使用[ThreadStatic]属性为每个线程创建单独的ISessionFactory。这允许我在每个线程上打开和关闭ISessions而不影响其他线程。