什么时候我需要在提交失败时回滚NHibernate事务?

时间:2014-02-06 17:22:41

标签: c# nhibernate transactions

我在NHibernate中关注this example on how to implement session-per-request次交易。

我有以下内容:

public class SessionManagementAttribute : ActionFilterAttribute
{
    private ISessionFactory SessionFactory { get; set; }

    public SessionManagementAttribute()
    {
        SessionFactory = WebApiApplication.SessionFactory;
    }

    public override void OnActionExecuting(ActionExecutingContext actionContext)
    {
        var session = SessionFactory.OpenSession();
        CurrentSessionContext.Bind(session);
        session.BeginTransaction();
    }

    public override void OnActionExecuted(ActionExecutedContext actionExecutedContext)
    {
        var session = SessionFactory.GetCurrentSession();
        var transaction = session.Transaction;
        if (transaction != null && transaction.IsActive)
        {
            //  TODO: Do I need to rollback a transaction here?
            transaction.Commit();
        }
        session = CurrentSessionContext.Unbind(SessionFactory);
        session.Close();
    }
}

我想知道 - 如果我的事务提交失败并抛出了NHibernate异常 - 我应该抓住它并回滚事务吗?在我当前的代码中,我有一个显式的catch和rollback。例如,

public void Save(Video video)
{
    try
    {
        NHibernateSessionManager.Instance.BeginTransaction();
        DoSave(video);
        NHibernateSessionManager.Instance.CommitTransaction();
    }
    catch (Exception exception)
    {
        Logger.Error(exception);
        NHibernateSessionManager.Instance.RollbackTransaction();
        throw;
    }
}

但是我在阅读材料中看到了这可能没有必要提示。任何人都可以澄清吗?

1 个答案:

答案 0 :(得分:0)

我们总是要处理会话。要么一切顺利,要么即使出现问题。看看这些:6.5. Lazy Initialization (引用)

  

在基于Web的应用程序中,只有在视图呈现完成后,才能在用户请求的最后使用事件处理程序close() ISession closed当然,这对应用程序基础结构的异常处理的正确性提出了很高的要求。 在返回用户之前,ISession为transactionLoad()已结束至关重要,即使在呈现视图期间发生异常 >。事件处理程序必须能够访问此方法的ISession。

另一个地方:9.2. Loading an object (引用)

  

...请注意,如果没有匹配的数据库行,ISession sess = factory.openSession(); try { // do some work ... sess.Flush(); currentTransaction.Commit(); } catch (Exception e) { currentTransaction.Rollback(); throw; } finally { sess.Close(); } 将抛出不可恢复的异常

但主要是:

9.8. Exception handling

摘录:

  

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

记录示例:

{{1}}

摘要

换句话说,会话处理是我们的责任。我们必须确保回滚被称为一些“外部环境”,可以在连接关闭时进行回滚...我们还必须确保会话在最后正确公开