当犯ASP.NET MVC 2应用程序NHibernate的交易? [英] When to commit NHibernate transactions in ASP.NET MVC 2 application?

查看:168
本文介绍了当犯ASP.NET MVC 2应用程序NHibernate的交易?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

First, some background: I'm new to ASP.NET MVC 2 and NHibernate. I'm starting my first application and I want to use NHibernate, because I come from JSP + Struts 1 + Hibernate web applications.

似乎没有人在谈论这一点,所以我想这一定是pretty明显。尽管如此,我帮我的头,因为我无法找到完成以下事情的解决方案:

No one seems to be talking about this, so I guess it must be pretty obvious. Still I scratch my head because I can't find a solution that accomplish the following things:

1)我想每个请求会话的策略使用。因此,每次用户发出请求时,他得到了NHibernate的会议上,启动了一个事务,当请求结束,事务提交,并NHibernate会话关闭(并返回到池中,如果有一个)。这保证了我的事务是原子的。

1) I want to use the "session per request" strategy. So, everytime a user makes a request, he gets an Nhibernate session, starts a transaction, and when the request is over, the transaction commits, and the NHibernate session closes (and returns to the pool if there is one). This guarantees that my transactions are atomic.

2)当数据库发生异常(PK侵犯,唯一侵犯,无论)我想要捕获该异常,回滚我的事务,并给用户一个明确的信息:如果是PK违规行为,则该消息,并同所有完整性错误。

2) When a database exception occurs (PK violation, unique violation, whatever) I want to capture that exception, rollback my transaction and give the user a explicit message: if it was PK violation, then that message, and the same with all integrity errors.

那么,什么是我的问题吗?我来自Java世界,在这里我用了一个过滤器来打开会话,启动事务,处理请求,然后提交事务并关闭会话。这工作,当数据库发生异常,除了,和你在过滤器中的时间有没有办法更改目标页面,因为响应已提交。

So, what is my problem? I come from the Java World, where I used a Filter to open the session, start the transaction, process the request, then commit the transaction and close the session. This works, except when an DB exception occurs, and by the time you are in the filter there's no way to change the destination page because the response is already committed.

因此​​,用户看到的成功页面时,现实中的交易被rollbacked。为了避免这种情况我已经写了很多在Java中的数据完整性检查,以prevent所有正直的例外,因为我不能正确处理它们。这是不好的,因为我做的工作,而不是把它留给数据库(或者也许我错了,我一直有写这些数据的完整性code在我的应用程序?)的。

So the user sees the success page when in reality the transaction was rollbacked. To avoid this I have to write a lot of data integrity checks in Java in order to prevent all integrity exceptions, because I could not handle them correctly. This is bad because I'm doing the work instead of leaving it to the database (or maybe I'm wrong and I always have to write all this data integrity code in my app?).

所以,我发现,我猜IHttpModule接口为pretty很多相同的概念作为一个javax.servlet.Filter的(纠正我,如果我错了),所以我猜我能有再次同样的问题。

So I've found the IHttpModule interface which I'm guessing is pretty much the same concept as a javax.servlet.Filter (correct me if I'm wrong), so I'm guessing I could have the same problem again.

我应该在哪里把我的提交,以确保我的事务是原子,而当他们抛出异常,我可以捕捉和改变我的目标页,给用户一个COM prehensive消息?

Where should I put my commits in order to make sure that my transactions are atomic, and when they throw exceptions I can capture them and change my destination page and give the user a comprehensive message?

目前为止唯一可能的解决方案,我想出了是让我IHttpModule的启动和关闭交易,把在我的控制器方法的最后一行提交调用,从而能够那里,然后捕捉异常返回的消息一个适当的视图。现在,我会复制这些承诺和异常处理线到需要提交所有的控制器方法。而且有顾虑的问题的分离,我的控制器必须了解数据库,这是我不喜欢的。

So far the only possible solution I've come up with is to keep my IHttpModule to start and close the transaction, and put the commit calls in the last line of my controllers methods, thus being able to capture exceptions there and then return an appropiate view with the message. Now I would have to copy those commit and exception handling lines into all my controller methods that require commits. And there is the separation of concerns issue, that my controllers have to know about DB, which I don't like at all.

有没有更好的办法?

推荐答案

经过考虑之后井与同事,我想出了满足几乎所有的需求的解决方案讨论它。

Well after thinking about it and discussed it with coworkers I've come up with a solution that meets almost all my requirements.

我实现了解决方案与我的Java项目和它的工作太棒了。我只是休闲区的想法所以每个人都可以在任何范围内使用它。

I implemented the solution with my Java projects and it worked great. I'll just pust the idea so everybody can use it within any framework.

该解决方案包括在把提交调用控制器方法的最后一行,一个try-catch块内。如果发生异常的限制,你可以得到的侵犯约束的名称。有了名字,你能确切说出了问题的用户。我用了一个属性文件来存储信息以显示给用户至极约束被侵犯。属性文件的关键是约束的名称和值是约束违规的消息。

The solution consist in putting the commit call in the last line of the controller method, inside a try-catch block. If a constraint exception occurs you can get the name of the violated constraint. With the name you can tell the user exactly what went wrong. I used a properties file to store the message to show to the user wich constraint was violated. The keys of the properties file are the constraints names and the values are the constraint violation messages.

哟可以重构提交 - handle_exception-find_constraint_message的方法,这就是我所做的。

Yo can refactor the commit-handle_exception-find_constraint_message to a method, that's what I did.

现在它解决了我的写作code的问题,检查数据库的完整性,我相信这是pretty优雅,在属性文件中的约束冲突的消息。现在,我还是不喜欢我的控制器需要调用commit的想法,但是这方式比写更完整检查数据库的已经做

For now it solves my problem of writing code to check database integrity and I believe it's pretty elegant with the constraint violation messages in a properties file. Now, I still don't like the idea that my controllers need to call the commit, but that's way better than writing integrity checks that the database already does.

我将继续使用过滤器,就像大卫·坎普说,只是过滤器将只打开(N)Hibernate的Session和事务,然后,在请求结束时关闭会话。

I will continue to use a filter just like David Kemp said, just that the filter will only open the (n)hibernate session and the transaction, and then, at the end of the request, close the session.

注释是无任欢迎。谢谢你。

Comments are more than welcome. Thanks.

这篇关于当犯ASP.NET MVC 2应用程序NHibernate的交易?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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