views:

28

answers:

2

I have created an IDbContext object that is provided to my IRepository implementations. The DbContext provides a way for my business logic to create, commit and rollback transactions and commits as needed. It also transports my NHibernate ISession, so my NHibernate implementation of IRepository can access it.

I am using this setup in a web application, where one DbContext is created per request and shared at by all repositories. At the end of the request, I dispose of the ISession.

Through your experience or knowledge of standard NHibernate practices, is it acceptable to have my DbContext flush and commit any outstanding transactions (provided there are no errors) automatically, when I'm disposing and about to close up my session?

A: 

Yes, last time I checked at least, I believe this is the architecture used in S#arp Architecture. It also makes sense logically I think - if there hasn't been any errors, why would you not want to commit everything to the database?

cbp
Yeah, it seems fairly straight-forward at first, but as Jamie Idle pointed out, that could be fairly late in the game to handle the error intelligently. I think the best answer lies (for my particular purposes) in flushing and committing open transactions, but following a strict pattern where errors within explicit transactions are caught, the transaction is rolled back, and the error is otherwise handled.
HackedByChinese
A: 

It's a common practice and is certainly acceptable, however it's not one I favor. I think it has a significant drawback in that the end of the request is too late to perform meaningful exception handling. I prefer to handle the transaction on the page so that I can catch exceptions and handle them there. In fact, I throw an exception in the EndRequest handler if the current ISession has an open transaction.

Jamie Ide
There is one scenario where I can see value in letting the DbContext manage the lingering transaction in the end, and that's where a series of different components work with the session and current transaction (we'd always have at least one transaction) to execute one after another. For example, the security layer might check roles, then the customization engine loads personal settings, then the meat of the request is serviced, and finally any auditing is recorded. I do see your point, though, and I'd prefer that we handle explict transactions, er... explicitly.
HackedByChinese