我在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;
}
}
但是我在阅读材料中看到了这可能没有必要提示。任何人都可以澄清吗?
答案 0 :(得分:0)
我们总是要处理会话。要么一切顺利,要么即使出现问题。看看这些:6.5. Lazy Initialization (引用):
在基于Web的应用程序中,只有在视图呈现完成后,才能在用户请求的最后使用事件处理程序
close()
ISession
closed
。 当然,这对应用程序基础结构的异常处理的正确性提出了很高的要求。 在返回用户之前,ISession为transaction
且Load()
已结束至关重要,即使在呈现视图期间发生异常 >。事件处理程序必须能够访问此方法的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(); }
将抛出不可恢复的异常。
但主要是:
摘录:
如果ISession抛出异常,您应该立即回滚事务,调用ISession.Close()并丢弃ISession实例。某些ISession方法不会使会话保持一致状态......
记录示例:
{{1}}
换句话说,会话处理是我们的责任。我们必须确保回滚被称为一些“外部环境”,可以在连接关闭时进行回滚...我们还必须确保会话在最后正确公开