在使用Ninject管理会话的请求期间发生异常时,如何回滚nHibernate事务? [英] How to rollback nHibernate transaction when an exception occurs during request having Ninject for managing sessions?

查看:100
本文介绍了在使用Ninject管理会话的请求期间发生异常时,如何回滚nHibernate事务?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将nHibernate用于ORM,将Ninject用于IoC. 我为每个自定义范围创建nHibernate会话(您可以假定是针对每个请求). 我开始交易onActivation. 我在onDeactivation上提交了交易.

I use nHibernate for ORM and Ninject for IoC. I create nHibernate sessions per some custom scope (which you can assume is per request). I begin the transaction onActivation. I commit the transaction onDeactivation.

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

The problem is that if an exception happens during the request I want to rollback the transaction rather than committing it. Any idea how to detect (in a clean way, most probably using Ninject Context) that an exception has happened?

注意:我并不担心提交时可能发生的异常,这些异常可以很容易地捕获到以下代码中,并且可以轻松地返回角色.

Note: I am not concerned about the exceptions that can happen on commit which I can catch in the following code and role back easily.

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();
            });
}

更新:

我遵循了@BatteryBackupUnit的建议. 因此,我将以下内容添加到错误EventHandler中:

I followed the suggestion by @BatteryBackupUnit. So I added the following to the Error EventHandler:

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

然后我将OnDeactivation修改如下:

And I modified the OnDeactivation to look like this:

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

                        t.Session.Dispose();
                    });

它可以正常工作,但是如果Ninject会在发生异常的情况下在Context中设置一个标志来解决这一问题,那将更好:)

It works fine, but that would be better if Ninject would take care of this by setting a flag in the Context if an exception happened :)

推荐答案

如何实现IHTTPModule并订阅Error事件? 如此处

How about implementing an IHTTPModule and subscribing to the Error event? Like described here

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

In the Error event handler, use System.Web.Mvc.DependencyResolver.Current.GetService(typeof (ISession)) to retrieve the current session and rollback the transaction.

但是请注意,如果请求不使用会话,则会创建一个会话,这是多余的.

Note, however, that in case the request did not use a session, this will create one, which is quite superfluous.

您可能会执行类似检查事务是否已开始然后才回滚的操作.但是您仍然会不必要地创建会话.

You might do something like checking whether a transaction was started and only then rolling it back. But you'd still create a session unnecessarily.

您可以通过使用Error事件处理程序在HttpContext.Current.Items上设置标志来进一步改善该效果,例如

You could further improve that by using the Error event handler to set a flag on HttpContext.Current.Items, like

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

,然后在会话的OnDeactivation中使用它,例如:

and then use it in the OnDeactivation of the session like:

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

请注意,HttpContext是线程本地的,这意味着当您切换线程时,它可能是null或-最坏的情况-甚至可能是另一个HttpContext.

Please note that HttpContext is thread local, that means when you switch threads it may be null or -worst case - it might even be another HttpContext.

还请注意,我无法尝试它,因此它可能无法正常工作.反馈表示赞赏.

Please also note that i was unable to try it out so it may not work. Feedback appreciated.

这篇关于在使用Ninject管理会话的请求期间发生异常时,如何回滚nHibernate事务?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆