HttpModule中的NHibernate会话和事务管理

时间:2023-02-15 20:58:09

I've seen many implementations on the web of people managing their NHibernate sessions and transactions in a HttpModule.

我在Web上看到很多人在HttpModule中管理他们的NHibernate会话和事务。

The HttpModule:

HttpModule:

  1. creates a session at the start of the request
  2. 在请求开始时创建会话
  3. wraps the whole request in a transaction
  4. 在事务中包装整个请求
  5. commits the transaction at the end of the request
  6. 在请求结束时提交事务

If people use this strategy how are they handling the following scenario:

如果人们使用此策略,他们如何处理以下场景:

  1. request comes in
  2. 请求进来
  3. retrieve object from database
  4. 从数据库中检索对象
  5. update object
  6. 更新对象
  7. object fails validation
  8. 对象验证失败
  9. changes to the object are still persisted because the transaction is committed in the HttpModule.
  10. 对象的更改仍然存在,因为事务是在HttpModule中提交的。

It seems that there is no good way to rollback the transaction in the above scenario. The only plan I can come up with is to:

在上面的场景中似乎没有好的方法来回滚事务。我能想出的唯一计划是:

  1. write my validation in such a way as it's guaranteed to succeed before updating my domain object (takes my validation out of my domain model).
  2. 以更新我的域对象之前保证成功的方式编写我的验证(从我的域模型中取出我的验证)。
  3. manage my transaction closer to my business logic and throw away the idea of doing it transparently in a HttpModule. (I've seen quite a few posts recommend this)
  4. 管理我的事务更接近我的业务逻辑,并抛弃在HttpModule中透明地执行它的想法。 (我看过不少帖子推荐这个)

Seeing as so many people seem to be using the HttpModule approach I'm hoping there is a third way of managing this scenario that I haven't thought of?

看到有这么多人似乎在使用HttpModule方法,我希望有第三种管理这种情况的方法,我没想过?

1 个解决方案

#1


2  

You can use some kind of global exception handling. Now I am using System.AppDomain.CurrentDomain.UnhandledException. In this handler you will need to call Transaction.Rollback(); And also condsider setting some flag (that also lives during current request only) that will point wehether you need to commit your transaction or roll back. This can make code more clear.

您可以使用某种全局异常处理。现在我正在使用System.AppDomain.CurrentDomain.UnhandledException。在此处理程序中,您将需要调用Transaction.Rollback();并且还考虑设置一些标志(仅在当前请求期间存在),这将标记您是否需要提交事务或回滚。这可以使代码更清晰。

Edit Alternativly you can use Error event of the HttpApplication

编辑Alternativly您可以使用HttpApplication的错误事件

public class HelloWorldModule : IHttpModule
{
    void Init(HttpApplication application)
    {
        application.BeginRequest += 
            (new EventHandler(this.Application_BeginRequest));
        application.EndRequest += 
            (new EventHandler(this.Application_EndRequest));
        //this is it
        applicaiton.Error +=
            (new EventHandler(this.Application_Error));
    }

#1


2  

You can use some kind of global exception handling. Now I am using System.AppDomain.CurrentDomain.UnhandledException. In this handler you will need to call Transaction.Rollback(); And also condsider setting some flag (that also lives during current request only) that will point wehether you need to commit your transaction or roll back. This can make code more clear.

您可以使用某种全局异常处理。现在我正在使用System.AppDomain.CurrentDomain.UnhandledException。在此处理程序中,您将需要调用Transaction.Rollback();并且还考虑设置一些标志(仅在当前请求期间存在),这将标记您是否需要提交事务或回滚。这可以使代码更清晰。

Edit Alternativly you can use Error event of the HttpApplication

编辑Alternativly您可以使用HttpApplication的错误事件

public class HelloWorldModule : IHttpModule
{
    void Init(HttpApplication application)
    {
        application.BeginRequest += 
            (new EventHandler(this.Application_BeginRequest));
        application.EndRequest += 
            (new EventHandler(this.Application_EndRequest));
        //this is it
        applicaiton.Error +=
            (new EventHandler(this.Application_Error));
    }