asp.net Nhibernate会话管理

时间:2011-12-26 10:15:16

标签: asp.net nhibernate session singleton

我在每个请求的asp.net会话中实现标准场景。 我的asp.net模块:

public class NHibernateSessionModule : IHttpModule
{
    public void Dispose() { }

    public void Init(HttpApplication context)
    {
        context.BeginRequest += context_BeginRequest;
        context.EndRequest += context_EndRequest;
    }

    void context_BeginRequest(object sender, EventArgs e)
    {
        var session = SessionManager.SessionFactory.OpenSession();
        session.BeginTransaction();
        CurrentSessionContext.Bind(session);

    }

    void context_EndRequest(object sender, EventArgs e)
    {
        var session = SessionManager.CurrentSession;
        if (session != null)
        {
            try
            {
                if (session.Transaction != null && session.Transaction.IsActive)
                    session.Transaction.Commit();
            }
            catch (Exception ex)
            {
                session.Transaction.Rollback();
                throw new ApplicationException("Error committing database transaction", ex);
            }
            finally
            {
                session.Close();
            }
        }
        CurrentSessionContext.Unbind(SessionManager.SessionFactory);
    }
}

我的sessionManager是线程安全的单例:

public class SessionManager
{
    private readonly ISessionFactory sessionFactory;
    public static ISessionFactory SessionFactory
    {
        get { return Instance.sessionFactory; }
    }
    private ISessionFactory GetSessionFactory()
    {
        return sessionFactory;
    }
    public static ISession OpenSession()
    {
        return Instance.GetSessionFactory().OpenSession();
    }
    public static ISession CurrentSession
    {
        get
        {
            if (!CurrentSessionContext.HasBind(Instance.GetSessionFactory()))
                return null;
            return Instance.GetSessionFactory().GetCurrentSession();
        }
    }


    public static SessionManager Instance
    {
        get
        {
            return NestedSessionManager.sessionManager;
        }
    }
    private SessionManager()
    {
        Configuration configuration = new Configuration().Configure();
        sessionFactory = configuration.BuildSessionFactory();
    }

    class NestedSessionManager
    {
        internal static readonly SessionManager sessionManager =
            new SessionManager();
    }
}

主要想法是在请求开始时打开会话,然后通过SessionManager.CurrentSession;

使用会话

会话存储在配置的上下文中:

<property name="current_session_context_class">web</property>

我的存储库:

public class RepositoryNew<T> : BaseRepository<T>, IDisposable
{
    public RepositoryNew()
    {
        if (NHibernateSession == null)
            //Start session for not web version
    }
    public void Dispose()
    {
        //flush session for not web version
    }

    protected override sealed ISession NHibernateSession
    {
        get
        {
            return SessionManager.CurrentSession; 
        }
    }
}

用法

protected void Page_Load(object sender, EventArgs e)
{          
    var repo = new RepositoryNew<Client>()
    clients = repo.GetAll();
}

由于某种原因,此存储库不在模块中使用已打开的会话。

CurrentSessionContext.HasBind(Instance.GetSessionFactory())

返回false,因此我的代码在请求中启动第二个会话。 在调试器中,我看到我已经两次立即调试了SessionManager。 我有两个不同的ISesssion工厂。 我还没有想法什么是错的。我花了很多时间。

2 个答案:

答案 0 :(得分:0)

在Http Begin Request中打开会话可能是另一回事,因为每个http请求都会像请求静态图像一样打开新会话,你必须改变这个策略,以便在每个Http请求中消除这个不必要的会话,你可以阅读这个博客并改变你的策略{{3 }}

答案 1 :(得分:0)

这是奇怪的错误。当我从项目中删除到SessionManager的链接时,它开始正常工作。