I need some insights and thoughts about a refactoring I'm about to do to our web-app.
We initially used the session-per-request pattern with NHibernate and ActiveRecord by using the On_BeginRequest / On_EndRequest in the HttpApplication to create and dispose the session. Later on, we realized that any DB-related exceptions got thrown outside of our monorail-context, meaning that our rescues didn't kick in. As another sideeffect, we didn't have the option to fully skip creation of NHibernate sessions in any action, which in some cases would be desirable.
So we rewrote it to create sessions in Initialize() / Contextualize() in our base controller, and disposed them in the Dispose() of our base controller. We also Rollback the session in our rescue controller to prevent any half written changes to the DB. So far, so good. The reason for doing it in the Dispose() is because we want it to live through the view-rendering, because of lazy-loading reasons aswell as viewcomponents that needs to get a session (we could switch to units-of-work for the viewcomponents, but they don't seem to have a Dispose()...)
However, I'm experiencing some deadlock issues where we have started transacations in the DB that isn't getting rollbacked nor committed and I can't get my head around it, mostly because of the mess we've made with this approach...
So I found this article: http://hackingon.net/post/NHibernate-Session-Per-Request-with-ASPNET-MVC.aspx
And I thought, "Filters, we can use that in MonoRail too!", because it can kick in on BeforeAction and AfterRendering.
My questions then are:
- What happens if an Exception occurs in the filter?
- Will AfterRendering fire even if an Exception occurs in the action or the rendering?
- Would you recommend this approach, if not, what are your suggestion instead?
Any pointers are very much appreciated!
You need an application error handler to care of exception handling.
Attach a debugger and find out.
Probably not (even though it is my article). It doesn't work with RenderAction. Best to use an IoC container to control the lifetime of connections.