当使用 Ninject 管理会话的请求期间发生异常时,如何回滚 nHibernate 事务?

2024-04-22

我使用 nHibernate 进行 ORM,使用 Ninject 进行 IoC。 我根据某个自定义范围(您可以假设是针对每个请求)创建 nHibernate 会话。 我在激活时开始交易。 我在停用时提交事务。

问题是,如果在请求期间发生异常,我想回滚事务而不是提交它。知道如何检测(以干净的方式,最有可能使用 Ninject Context)发生异常吗?

注意:我不关心提交时可能发生的异常,我可以在下面的代码中捕获这些异常并轻松返回。

protected void BindWithSessionWrapper<T>(Func<IContext, T> creationFunc) where T : ISessionWrapper
{
    Bind<T>().ToMethod(creationFunc)
        .InScope(x => new NinjectCustomScope()) // work in progress !!!
        .OnActivation(t => t.Session.BeginTransaction(IsolationLevel.ReadCommitted))
        .OnDeactivation((c, t) => 
            { 
                t.Session.Transaction.Commit();
                t.Session.Dispose();
            });
}

Update:

我遵循了@BatteryBackupUnit 的建议。 所以我将以下内容添加到错误事件处理程序中:

    Error += (s, e) =>
        {
            HttpContext.Current.Items["ErrorRaised"] = true;
        };

我将 OnDeactivation 修改为如下所示:

OnDeactivation(t => 
                    { 
                        if ((bool?)HttpContext.Current.Items["ErrorRaised"] == true)
                            t.Session.Transaction.Rollback();
                        else
                            t.Session.Transaction.Commit();

                        t.Session.Dispose();
                    });

它工作得很好,但是如果 Ninject 在发生异常时通过在上下文中设置一个标志来解决这个问题,那就更好了:)


怎么样实施一个IHTTPModule并订阅Error事件? 就像描述的那样here http://msdn.microsoft.com/en-us/library/ff649096.aspx

In the Error事件处理程序,使用System.Web.Mvc.DependencyResolver.Current.GetService(typeof (ISession))检索当前会话并回滚事务。

但请注意,如果请求未使用会话,这将创建一个会话,这是相当多余的。

您可能会执行一些操作,例如检查事务是否已启动,然后才将其回滚。但您仍然会创建不必要的会话。

您可以通过使用进一步改进Error设置标志的事件处理程序HttpContext.Current.Items, like

HttpContext.Current.Items["RollbackTransaction"] = true;

然后在中使用它OnDeactivation会议的像:

    .OnDeactivation((c, t) => 
        { 
            if(HttpContext.Current.Items.Contains("RollbackTransaction"])
            {
                t.Session.Transaction.Rollback();
            }
            else
            {
                t.Session.Transaction.Commit();
            }
            t.Session.Dispose();
        });

请注意HttpContext是线程局部的,这意味着当你切换线程时它可能是null或者-最坏的情况-甚至可能是另一种情况HttpContext.

另请注意,我无法尝试,因此它可能不起作用。感谢反馈。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

当使用 Ninject 管理会话的请求期间发生异常时,如何回滚 nHibernate 事务? 的相关文章

随机推荐