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



我正在按照这个例子学习如何在NHibernate中实现每个请求的会话事务。

我有以下几点:

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 异常 - 我应该捕获它并回滚事务吗?在我当前的代码中,我有一个明确的捕获和回滚。例如

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

但我通过阅读看到了暗示,这可能没有必要。谁能澄清一下?

我们总是必须处理会话。要么一切顺利,但即使出现问题。看看这些: 6.5.延迟初始化(引用):

在基于 Web 的应用程序中,事件处理程序可用于仅在用户请求结束时(视图呈现完成后)close()ISession当然,这对应用程序基础结构异常处理的正确性提出了很高的要求。至关重要的是,在返回给用户之前closedISession 并结束transaction,即使在呈现视图期间发生异常也是如此。事件处理程序必须能够访问此方法的 ISession。

另一个地方:9.2。加载对象(引用)

。请注意,如果没有匹配的数据库行,Load()将引发不可恢复的异常

但主要是:

9.8. 异常处理

摘录:

如果 ISession 引发异常,您应该立即回滚事务,调用 ISession.Close() 并丢弃 ISession 实例。某些 IS ession 方法不会使会话处于一致状态...

记录的示例:

ISession sess = factory.openSession();
try
{
// do some work
...
sess.Flush();
currentTransaction.Commit();
}
catch (Exception e)
{
currentTransaction.Rollback();
throw;
}
finally
{
sess.Close();
}

总结

换句话说,会话处理是我们的责任。我们必须确保回滚是针对一些"外部环境"调用的,这些"外部情况"可以在连接关闭时进行回滚......我们还必须确保会话在最后正确公开

最新更新