【问题标题】:ISession per Request (Only when necessary)每个请求的 ISession(仅在必要时)
【发布时间】:2010-09-13 20:55:25
【问题描述】:

我正在开发一个应用程序 (asp.net mvc),并且我在每个请求中使用 ISession(在 globa.asax 中,我在 Begin_Request 事件和 End_Request 事件中使用 Bind 和 Unbind)。一切正常,但有时(某些请求)我不需要使用 ISession(与数据库的连接)。

我想知道是否有任何方法仅在我需要时打开 ISession 并在所有进程请求中创建 ISession 条目(与所有存储库和唯一的事务上下文共享)?

我正在开发一分钱拍卖网站,我的服务器每秒会有很多请求,有时我不需要连接,我会使用缓存。

谢谢

干杯

【问题讨论】:

    标签: nhibernate orm request sessionfactory isession


    【解决方案1】:

    需要注意的是,打开会话并不意味着打开与数据库的连接。如this article 中所述,打开会话的成本极低。所以,一般来说,我不会担心请求在不需要时打开会话;本质上,您只是在新建一个非常轻量级的对象。

    【讨论】:

    • 我不知道,也许它没有问题。谢谢!
    • 如果您需要鸟瞰NHibernate 幕后发生的事情,我强烈推荐NHProf。如果不出意外,这应该有助于验证在 emtpy 会话中没有发生数据库交互。
    • 嗨@DanP,是的,我正在使用 NHProf 查看更多详细信息,实际上有些页面我得到了一个空会话。我将实现一分钱拍卖的计时器,我的应用程序每秒都会有一个请求。就像你推荐和Ayenge文章一样,不会有问题=D。谢谢
    【解决方案2】:

    您可以使用 ActionFilter 来执行此操作。这是我用来完全按照您的描述进行操作的方法。

    public class UsingNhibernate : ActionFilterAttribute {
        private ISession nhSession;
        public override void OnActionExecuting(ActionExecutingContext filterContext) {
            nhSession = NHHelper.OpenSession();
            nhSession.BeginTransaction();
            // set an accessible reference to your nhSession for access from elsewhere
            //   ((ApplicationController)filterContext.Controller).nHSession = nhSession; is what I do
            base.OnActionExecuting(filterContext);
        }
    
        public override void OnActionExecuted(ActionExecutedContext filterContext) {
            try {
                if (filterContext.Exception == null && nhSession != null && nhSession.Transaction.IsActive)
                    nhSession.Transaction.Commit();
                else if (nhSession != null && nhSession.Transaction.IsActive)
                    nhSession.Transaction.Rollback();
            } catch (Exception ex) {
                if (nhSession != null && nhSession.Transaction.IsActive)
                    nhSession.Transaction.Rollback();
                nhSession.Dispose();
                throw;
            }
            nhSession.Dispose();
            base.OnActionExecuted(filterContext);
        }
    }
    

    在每个适当的控制器操作(甚至在控制器级别应用到所有操作)上,您只需添加 UsingNhibernate 操作过滤器,如下所示:

    [UsingNhibernate]
    public ActionResult SaveSystemSetting(SystemAdminVM item) {
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-01-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多