刷新页面时NHibernate会话关闭 [英] NHibernate session is closed when refreshing page

查看:77
本文介绍了刷新页面时NHibernate会话关闭的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我这几天遇到的另一个奇怪的问题!!!我已经使用nhibernate创建了MVC 4应用程序.并在HomeController上添加了一个名为[LoggingNHibernateSessionAttribute]的过滤器属性,该属性管理每个操作的会话.我遵循了"ASP.NET MVC4和Apress发布的Web API".

This is another strange problem I've encountered this days!!! I've created and MVC 4 app using nhibernate. and added a filter attribute named [LoggingNHibernateSessionAttribute] on my HomeController which manages session for each action. I've followed 'ASP.NET MVC4 and the Web API published by Apress'.

public class LoggingNHibernateSessionAttribute : ActionFilterAttribute
{
    private readonly IActionLogHelper _actionLogHelper;
    private readonly IActionExceptionHandler _actionExceptionHandler;
    private readonly IActionTransactionHelper _actionTransactionHelper;

    public LoggingNHibernateSessionAttribute()
        : this(WebContainerManager.Get<IActionLogHelper>(),
        WebContainerManager.Get<IActionExceptionHandler>(),
        WebContainerManager.Get<IActionTransactionHelper>())
    {
    }

    public LoggingNHibernateSessionAttribute(
        IActionLogHelper actionLogHelper,
        IActionExceptionHandler actionExceptionHandler,
        IActionTransactionHelper actionTransactionHelper)
    {
        _actionLogHelper = actionLogHelper;
        _actionExceptionHandler = actionExceptionHandler;
        _actionTransactionHelper = actionTransactionHelper;
    }

    public override void OnActionExecuting(ActionExecutingContext actionExectingContext)
    {
        _actionLogHelper.LogEntry(actionExectingContext.ActionDescriptor);
        _actionTransactionHelper.BeginTransaction();
    }

    public override void OnActionExecuted(ActionExecutedContext actionExecutedContext)
    {
        _actionTransactionHelper.EndTransaction(actionExecutedContext);
        _actionTransactionHelper.CloseSession();
        _actionExceptionHandler.HandleException(actionExecutedContext);
        _actionLogHelper.LogExit(actionExecutedContext.ActionDescriptor);
    }
}

ActionTransactionHelper

ActionTransactionHelper

  public class ActionTransactionHelper : IActionTransactionHelper
{
    private readonly ISessionFactory _sessionFactory;
    private readonly ICurrentSessionContextAdapter _currentSessionContextAdapter;

    public ActionTransactionHelper(
        ISessionFactory sessionFactory,
        ICurrentSessionContextAdapter currentSessionContextAdapter)
    {
        _sessionFactory = sessionFactory;
        _currentSessionContextAdapter = currentSessionContextAdapter;
    }

    public void BeginTransaction()
    {
        var session = _sessionFactory.GetCurrentSession();
        if (session != null)
        {
            session.BeginTransaction();
        }
    }

    public bool TransactionHandled { get; private set; }

    public void EndTransaction(ActionExecutedContext filterContext)
    {
        var session = _sessionFactory.GetCurrentSession();

        if (session == null) return;
        if (!session.Transaction.IsActive) return;

        if (filterContext.Exception == null)
        {
            session.Flush();
            session.Transaction.Commit();
        }
        else
        {
            session.Transaction.Rollback();
        }

        TransactionHandled = true;
    }

    public bool SessionClosed { get; private set; }

    public void CloseSession()
    {
        if (_currentSessionContextAdapter.HasBind(_sessionFactory))
        {
            var session = _sessionFactory.GetCurrentSession();
            session.Close();
            session.Dispose();
            _currentSessionContextAdapter.Unbind(_sessionFactory);

            SessionClosed = true;
        }
    }
}

运行该应用程序时,我可以将一个实体保存在数据库中.但是当我按下刷新"按钮并且抛出异常的指示会话关闭时.

when run the app, I can save an entity in the dataBase. but when I hit refresh button and exception thrown indication session is closed.

我不知道为什么会这样. (我搜索并发现此 NHibernate投掷会话已关闭,但无法解决我的问题).

I don't know why this happens. (I searched and find this NHibernate throwing Session is closed but couldn't solve my problem).

在我的NinjectConfigurator中,我将inRequestScope()添加到所有注入中,但没有答案.我检查了刷新页面会话的时间.但我不知道为什么会说会话关闭?!

in my NinjectConfigurator I added inRequestScope() to all of injections but no answer. I checked when I refresh the page session will be opened. but I donnow why it say session is closed?!

更新:

当我第一次运行该应用程序时.我可以创建一个新成员.但是当我按下刷新按钮时,会话将意外关闭! 第一次运行:

when I first run the app. I can create a new member. but when I hit the refresh button, the session will be closed unexpectedly!! first run:

  1. 一切正常

点击刷新按钮后:

  1. 新会话绑定到当前上下文.
  2. 新会话将被注入到存储库中(会话处于打开状态)
  3. ActionTransactionHelper调用beginTransaction() 4- customMembership createUser(....)称为 5-但是在存储库会话中调用的_userRepositoy.save(user)关闭时!!!
  1. a new session bind to the current context.
  2. the new session will be injected the repository (session is open)
  3. the ActionTransactionHelper calls beginTransaction() 4- customMembership createUser (....) called 5- but when the _userRepositoy.save(user)called in the repository session is closed!!!!

note:但是当仍未调用endTransaction和closeSession时.但是会话如何关闭? 如果我在onActionExecute()中评论closeSession().会话始终处于打开状态,如果刷新页面,一切都会正常进行. 我进行了很多检查,并尝试了不同的方法.只有在第二次我想使用customMembership进行CRUD操作时,这种情况才会发生.

note:but when still endTransaction and closeSession isn't called. but how session is closed? if I comment closeSession() in onActionExecute(). session alway is open and everything woks well if refresh the page. I checked a lot and tried different way I knew. it only happens when for the second time I want to do CRUD operations with my customMembership.

对于其他实体,它就像一个魅力! 我已经修改了示例代码.用于测试的只是创建和清空数据库并更改连接字符串.然后转到localHost:*****/api/categories(不需要用户和密码)

for other entities it works like a charm! I have upoaded my sample code. for testing just create and empty database and change connection string. then go to localHost:*****/api/categories (user and pass doesn't required)

下载示例项目: 大小:47 MB https://www.dropbox.com/s/o63wjng5f799fii/Hashem-MVC4ServicesBook. rar

Download sample project: Size: 47 MB https://www.dropbox.com/s/o63wjng5f799fii/Hashem-MVC4ServicesBook.rar

大小:54 MB 邮编格式: https://www.dropbox.com/s/smrsbz4cbtznx1y/Hashem -MVC4ServicesBook2.zip

size: 54 MB Zip Format: https://www.dropbox.com/s/smrsbz4cbtznx1y/Hashem-MVC4ServicesBook2.zip

推荐答案

在这里很重要的一点可能就是NHibernate的本质. NHibernate及其Session在ASP.NET MVC中的寿命更长,因此可以预期.我的意思是不仅在

A very important thing here, could be the nature of the NHibernate. The NHibernate and its Session are in the ASP.NET MVC living longer, then could be expected. I mean not only inside of the

  • 动作执行(控制器动作开始)
  • 已执行动作(称为视图"或重定向")

会话也必须经历渲染阶段.因为,我们可以在"Action()"中加载某些 proxy ,但只能在View渲染期间加载lazily.因此,即使在这些阶段中,也必须打开Session(从请求开始的同一会话)

Session in fact must live also through the phase of rendering. Because, we could load some proxy in the "Action()" but its collection, could be lazily loaded only during the View rendering. So even in these phases Session must be opened (the same Session from the request begining)

  • ResultExecuting(只能在此处开始加载代理)
  • ResultExecuted(几乎已完成,让我们关闭会话)

换句话说... 保留整个请求中打开的会话.从授权到呈现内容.

Other words... keep the session opened throught the complete Request. From authorization untill the content is rendered.

注意:提示,只是为了确保一切正常,我正在使用这种情况(也许您也可以这样做):

NOTE: Anohter hint, just to be sure that all is ok, I am using this scenario (maybe you do as well):

  1. 客户端FORM即将向服务器发送数据.方法是POST,操作是Update()
  2. 已发送FORM到服务器,触发了Action Update()-所有交易内容均已就绪(如上所述)
  3. 一旦NHibernate将数据持久保存到数据库中,Update()操作将结束,并重定向到该操作
    • Detail()(如果一切正常)或
    • Edit()如果出了什么问题
  1. Client FORM is about to send the data to server. The method is POST, the Action is Update()
  2. Sent FORM is coming to server, Action Update() is triggerred - all the transactions stuff is in place (as described above)
  3. Once NHibernate persists the data into DB, the Update() action ends, and is redirected to action
    • Detail() if all is ok or
    • Edit() if something goes wrong

实际上,步骤 1.是操作DetailEdit之一.在这种情况下,我们将已经面临这个问题...

In fact, the step 1. was one of the Actions Detail or Edit. In this case, we would face this issue already...

这篇关于刷新页面时NHibernate会话关闭的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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