NHibernate Transaction.Commit 自动关闭Session [英] NHibernate Transaction.Commit automatically closes Session

查看:49
本文介绍了NHibernate Transaction.Commit 自动关闭Session的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个使用绝对最新版本 (3.3) 的 Web 应用程序,并且在 HttpModule 中使用逐个请求的会话管理,因此没有多个会话冲突的问题.不幸的是,我发现会话在我执行 Transaction.Commit 后立即自动关闭,我只在我实际执行创建、更新或删除时才这样做.我在我的 NHibernate 日志中找到了这个.

I have a web application that is using the absolute latest version (3.3) and is using session-by-request session management within a HttpModule, so there are no problems with multiple session conflicts. Unfortunately, I am finding that the session is getting automatically closed immediately after I perform a Transaction.Commit which I only do when I am actually performing a Create, Update or Delete. I am finding this within my NHibernate log.

我知道我没有这样做,因为对 ISession.Close 函数的唯一调用是在我的 HttpModule 中完成的.

I know for a fact that I am not doing it, because the only call to the ISession.Close function is being done within my HttpModule.

是的,当然我可以在我的 SessionManager 中放置代码来检查 IsClosed 参数,然后使用 OpenSession 函数而不是 GetCurrentSession,但这是否应该发生?有什么方法可以通过我的配置或我可以在 Session 或 Transaction 对象上设置的某些属性来防止这种情况发生,或者这只是我在任何地方都找不到任何文档的新功能之一?

Yes, of course I can put code in my SessionManager to check for the IsClosed parameter and then use the OpenSession function instead of GetCurrentSession, but should this even be happening? Is there some way that I can prevent this either through my configuration or some attribute that I could set on the Session or Transaction object or is this just one of the new features that I can't find any documentation anywhere on?

请帮忙.

布莱恩

我被要求提供一些代码,所以这是 HttpModule 的代码:

I was asked to provide some code, so here is the code for the HttpModule:

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

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

    public void context_BeginRequest(Object sender, EventArgs e)
    {
        WebSessionContext.Bind(NhibernateSessionManager.GetContextSession());
    }

    public void context_EndRequest(Object sender, EventArgs e)
    {
        ISession session = WebSessionContext.Unbind(NhibernateSessionManager.SessionFactory);

        if (session != null)
        {
            if (session.Transaction != null && session.Transaction.IsActive)
            {
                session.Transaction.Rollback();
            }
            else
                session.Flush();

            session.Close();
        }
    }
}

}

接下来,您将找到我在 SessionManager 中使用的原始代码:

Next, you will find the original code that I am using within my SessionManager:

public sealed class NhibernateSessionManager
{
    private readonly ISessionFactory sessionFactory;
    public static ISessionFactory SessionFactory
    {
        get { return Instance.sessionFactory; }
    }

    private ISessionFactory GetSessionFactory()
    {
        return sessionFactory;
    }

    public static NhibernateSessionManager Instance
    {
        get { return NestedSessionManager.sessionManager; }
    }

    public static ISession GetContextSession()
    {
        ISession session;
        if (CurrentSessionContext.HasBind(SessionFactory))
        {
            session = SessionFactory.GetCurrentSession();
        }
        else
        {
            session = SessionFactory.OpenSession();
            CurrentSessionContext.Bind(session);
        }
        return session;
    }  

    private NhibernateSessionManager()
    {
        if (sessionFactory == null)
        {
            Configuration configuration;
            configuration = new Configuration().Configure(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "web.config"));
            log4net.Config.XmlConfigurator.ConfigureAndWatch(new FileInfo(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "web.config")));

            //Configuration configuration = new Configuration().Configure();
            if (configuration == null)
            {
                throw new InvalidOperationException("NHibernate configuration is null.");
            }
            else
            {
                sessionFactory = configuration.BuildSessionFactory();
                if (sessionFactory == null)
                    throw new InvalidOperationException("Call to BuildSessionFactory() returned null.");
            }
        }
    }

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

最后,这是一个当前导致会话在 Transaction.Commit() 之后立即关闭的函数.每个内部函数都会检索当前会话,然后处理 Save 调用.

Last, here is a function that is currently causing the session to close immediately after the Transaction.Commit(). Each of the inner functions retrieve the current session and then process a Save call.

    public static Int32 AddVideo(VideoFile Video, Int32 UserID, Int16 InstID)
    {
        log.Debug("Begin AddVideo");
        Int32 FileID = 0;

        using (ISession Session = NhibernateSessionManager.GetContextSession())
        {
            using (ITransaction Transaction = Session.BeginTransaction())
            {
                Video.Created = DateTime.Now;
                Video.Modified = DateTime.Now;

                FileID = (Int32)Session.Save(Video);
                Video.FileID = FileID;

                // Need to process through all the categories and insert records into the ivxFileCategories table
                // to associate the newly created file with the chosen categories
                if (Video.CategoryAssociations != null)
                {
                    log.Info("Number of categories to be associated with the video: " + Video.CategoryAssociations.Count);
                    for (int i = 0; i < Video.CategoryAssociations.Count; i++)
                    {
                        CategoryFileAssociation Assoc = (CategoryFileAssociation)Video.CategoryAssociations[i];
                        Assoc.FileID = FileID;
                        AssociationManager.AddCategoryFileTransaction(Assoc);
                    }
                }

                // Need to add the default file access for the UserDetail that is creating the new video which will always
                // be Admin because the UserDetail creating a file should always have admin access over the file, no matter
                // what their default role is.
                AssociationManager.AddFileAccessTransaction(FileID, UserID, UserClassConstants.IVXUSERCLASS_ADMIN);

                // Need to add the institutional association based on whether the new video was created by a librarian
                // or one of the iVidix admins
                AssociationManager.AddInstitutionFileTransaction(InstID, FileID);

                Transaction.Commit();
            }
        }

        log.Debug("End AddVideo");
        return FileID;
    }

推荐答案

会话将在 AddVideo 方法中处理,因为您使用的是 使用语句进行会话.

The session will by disposed in the AddVideo method because you are using the using Statement for the session.

using (ISession Session = NhibernateSessionManager.GetContextSession())
{

}

这篇关于NHibernate Transaction.Commit 自动关闭Session的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆