何时在ASP.NET MVC 2应用程序中提交NHibernate事务?

Jua*_*des 5 nhibernate transactions commit asp.net-mvc-2

首先,一些背景:我是ASP.NET MVC 2和NHibernate的新手.我正在开始我的第一个应用程序,我想使用NHibernate,因为我来自JSP + Struts 1 + Hibernate Web应用程序.

似乎没有人在谈论这个,所以我想这一定是非常明显的.我仍然挠头,因为我找不到能够完成以下事情的解决方案:

1)我想使用"每个请求的会话"策略.因此,每次用户发出请求时,他都会获得Nhibernate会话,启动事务,当请求结束时,事务提交,NHibernate会话关闭(如果存在则返回池).这保证了我的交易是原子的.

2)当发生数据库异常(PK违规,唯一违规,无论如何)时,我想捕获该异常,回滚我的事务并给用户一个明确的消息:如果是PK违规,那么该消息,以及所有完整性相同错误.

那么,我的问题是什么?我来自Java World,我使用Filter打开会话,启动事务,处理请求,然后提交事务并关闭会话.这有效,除非发生数据库异常,并且当您进入过滤器时,无法更改目标页面,因为响应已提交.

因此,当实际交易被回滚时,用户会看到成功页面.为了避免这种情况,我必须在Java中编写大量数据完整性检查,以防止所有完整性异常,因为我无法正确处理它们.这很糟糕,因为我正在做的工作而不是把它留给数据库(或者我错了,我总是要在我的应用程序中编写所有这些数据完整性代码?).

所以我发现我猜的IHttpModule接口与javax.servlet.Filter的概念基本相同(如果我错了,请纠正我),所以我猜我可能会再遇到同样的问题.

我应该在哪里提交我的提交以确保我的事务是原子的,当它们抛出异常时我可以捕获它们并更改我的目标页面并给用户一个全面的消息?

到目前为止,我提出的唯一可能的解决方案是保持我的IHttpModule启动和关闭事务,并将提交调用放在我的控制器方法的最后一行,从而能够捕获那里的异常,然后返回适当的查看消息.现在我必须将这些提交和异常处理行复制到我需要提交的所有控制器方法中.并且存在关注点分离问题,我的控制器必须知道DB,我完全不喜欢它.

有没有更好的办法?

Jua*_*des 0

经过思考并与同事讨论后,我想出了一个几乎可以满足我所有要求的解决方案。

我用我的 Java 项目实现了该解决方案,效果非常好。我将把这个想法提出来,以便每个人都可以在任何框架中使用它。

解决方案包括将提交调用放在控制器方法的最后一行的 try-catch 块内。如果发生约束异常,您可以获得违反约束的名称。通过名称,您可以准确地告诉用户出了什么问题。我使用属性文件来存储消息,以向用户显示违反了约束的情况。属性文件的键是约束名称,值是约束违反消息。

您可以将 commit-handle_exception-find_constraint_message 重构为一个方法,这就是我所做的。

目前,它解决了我编写代码来检查数据库完整性的问题,并且我相信它对于属性文件中的约束违规消息非常优雅。现在,我仍然不喜欢我的控制器需要调用提交的想法,但这比编写数据库已经执行的完整性检查要好得多。

我将继续使用过滤器,就像 David Kemp 所说的那样,只是过滤器只会打开 (n)hibernate 会话和事务,然后在请求结束时关闭会话。

非常欢迎发表评论。谢谢。