nhibernate会话管理器实现

时间:2012-02-09 18:31:50

标签: asp.net nhibernate design-patterns singleton

我是Nhibernate的新手,通过学习它来减慢工作速度。我试图实现一个会话管理器类来帮助我获取db调用的会话。下面是它的代码。有人可以说,如果这在架构上是正确的,并预见到任何可扩展性或性能问题吗?

public static class StaticSessionManager
{
    private static ISession _session;

    public static ISession GetCurrentSession()
    {
        if (_session == null)
            OpenSession();

        return _session;
    }

    private static void OpenSession()
    {
        _session = (new Configuration()).Configure().BuildSessionFactory().OpenSession();
    }
    public static void CloseSession()
    {
        if (_session != null)
        {
            _session.Close();
            _session = null;
        }
    }
}

在我的数据提供程序类中,我使用以下代码来获取数据。

    public class GenericDataProvider<T>
    {
            NHibernate.ISession _session;

            public GenericDataProvider()
            {
                this._session = StaticSessionManager.GetCurrentSession();
            }

            public T GetById(object id)
            {
                using (ITransaction tx = _session.BeginTransaction())
                {
                    try
                    {
                        T obj = _session.Get<T>(id);
                        tx.Commit();
                        return obj;
                    }
                    catch (Exception ex)
                    {
                        tx.Rollback();
                        StaticSessionManager.CloseSession();
                        throw ex;
                    }
                }
            }
    }

然后

public class UserDataProvider : GenericDataProvider<User>
{
    public User GetUserById(Guid uid)
    {
        return GetById(uid)

    }
}

Page

中的最终用法
UserDataProvider  udp = new UserDataProvider();
User u = udp.GetUserById(xxxxxx-xxx-xxx);

这是正确的吗?在单个页面中实例化大量数据提供程序会导致问题吗?

我现在也面临一个问题,如果我同时从多台机器执行相同的读取操作,Nhibernate会抛出随机错误 - 我认为这是由于交易造成的。

请建议。

1 个答案:

答案 0 :(得分:2)

如果您有null会话,我可以看到您正在构建会话工厂。您只应在应用程序启动时调用BuildSessionFactory()一次。

您执行此操作取决于您,有些人在方法SessionFactory中的Global.asax内部构建application_start,或者在您的情况下为sessionFactory而不是{session构建静态属性{1}}课程中的{1}}。

我怀疑您的错误是由于您的会话工厂正在多次构建!

另一点是,有些人会在每个请求开始时打开一个事务StaticSessionManager,并在每个请求结束时打开_session.BeginTransaction()commit。这为您提供了一个工作单元,这意味着您可能会失去

rollback

关于每个方法。所有这些都是开放的辩论,但我使用这种方法99%的代码完全没有问题。