每个请求和异常管理的nHibernate会话

时间:2012-12-28 04:19:30

标签: nhibernate exception session-per-request

我有一个与此类似的场景: Asp.NET MVC 4网站使用nHibernate Session Per Request。 使用Ninject将会话注入到具有Get和Save方法的Repository中。

有很多文章都在讨论Session Per Request,并说这是在Web应用程序上做事的方法。

但是我在实现像这样的逻辑时遇到了问题:

Read Data From Database
Alter Entity information
Save to Database
Read another entity
Alter entity
Save ... but an EXCEPTION OCCURS

我希望向用户显示我的观看消息。但我还要刷新生成的网页, 所以我还要从数据库中读取一些信息。

根据nHibernate文档,必须丢弃具有异常的会话Documentation Here

但我找不到任何有关最佳方式的文章。

这种情况的最佳方法是什么?我将不得不向我的存储库对象注入一个新的会话?。

感谢。

1 个答案:

答案 0 :(得分:4)

您可以从原始会话的SessionFactory属性创建新会话。您可以通过在存储库类中公开它或将其注入控制器来访问原始会话对象。然后,您可以使用新会话创建新的存储库。

我在我的一些操作中执行此操作,我希望发生唯一的密钥违规,并且我必须在模型中重新加载查找数据。这是一个例子:

    public ActionResult Create(MeasuresEditView model)
    {
        if (ModelState.IsValid)
        {
            using (var txn = _session.BeginTransaction())
            {
                try
                {
                    var measure = new Measure { Code = model.Code };
                    _session.Save(measure);
                    txn.Commit();
                    return RedirectToAction("Index");
                }
                catch (UniqueKeyException)
                {
                    txn.Rollback();
                    var msg = string.Format("A measure with the code '{0}' already exists, please enter a different code or cancel.", model.Code);
                    ModelState.AddModelError("Code", msg);
                }
                catch (Exception ex)
                {
                    if (txn.IsActive)
                    {
                        txn.Rollback();
                    }
                    log.Error("Create", ex);
                    throw;
                }
            }
        }
        // have to rebuild selectlist on post in new txn in case it was rolled back
        using (var session = _session.SessionFactory.OpenSession())
        using (var txn = session.BeginTransaction())
        {
            SetProductGroupSelectList(session, model, manualId);
            txn.Commit();
        }
        return View(model);
    }