【问题标题】:NHibernate ISession: Nothing can be persisted after an ExceptionNHibernate ISession:异常后没有任何东西可以持久化
【发布时间】:2012-04-05 17:47:07
【问题描述】:

我对 NHibernate ISession 有疑问。当我尝试将错误保存到数据库中时(例如,在 XYZ col 上保存具有重复键的实体)并回滚 Transaction; ISession 实例进入 BROKEN/INVALID 状态,此后不会保留任何记录,并且每次 NHibernat 抛出另一个异常,告诉我第一次问题。

我使用了像 Flush, Clear, Close 这样的 ISession 方法,但我的问题存在。另一种方法是从ISessionFactory 请求另一个ISession 实例,但是当我使用它时,另一个奇怪的问题是:illegal attempt to associate a collection with two open sessions

如何在不从 ISessionFactory 重新请求另一个 ISession 实例的情况下恢复 ISession 实例?

提前致谢:)

【问题讨论】:

  • 你有这个模型的延迟加载属性吗?
  • 是的!很多延迟加载的属性(导航、集合)
  • 如果您请求某些属性可能会出现问题。

标签: asp.net-mvc nhibernate isession


【解决方案1】:

您无法恢复 ISession。来自documentation

如果 ISession 抛出异常,你应该立即回滚 事务,调用 ISession.Close() 并丢弃 ISession 实例。 ISession 的某些方法不会将会话留在 一致的状态。

还有creating ISession is cheap,所以没有理由尝试重复使用它。如果您有 MVC 应用程序,您可能希望每个请求都有 ISession。

【讨论】:

    【解决方案2】:

    你不能,也不应该。

    如果事务失败,您必须中止请求并显示错误。

    逻辑推论是会话异常不应成为您常规流程的一部分。

    现在,由于您使用的是 MVC,下面是一个示例,说明如果您允许错误,错误处理可能如何工作:

    public ActionResult CreateFoo(FooModel model)
    {
        if (ModelState.IsValid)
        {
            try
            {
                SaveThe(model);
                TheTransaction.Commit();
                return RedirectToAction("Whatever");
            }
            catch (WhateverTheDuplicateKeyExceptionIs)
            {
                ModelState.AddModelError("", "Duplicate XYZ");
            }
        }
        return View();
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-22
      • 1970-01-01
      • 1970-01-01
      • 2018-02-18
      • 1970-01-01
      相关资源
      最近更新 更多