I would like to be able to rerun transactions if a deadlock occurs. In Ayende's blog post he mentions that you need to throw away the whole NHibernate session and start again.
Restarting the session is relatively straightforward in a Windows app, but how would you do this in a web app when using the Session-Per-Request module? The session is opened and closed inside an IHttpModule. The only way I can think of is to reissue the http post somehow. This would be fiddly, and could also end up re-executing other transactions that had already been committed successfully (as we have multiple transactions per Session).
You need to expose the ISessionFactory somehow so you can use it to create a new ISession when needed. A quick solution would be to set a static property in global.asax.
Related
I wonder what is the best way to manage NHibernate Session Context
when using NH data layer from Xsockets controller.
Particularly I refer to self hosted winservice/console application or Azure worker role,
where HTTPContext is not available.
Of course there is always an option to create and dispose session per call, but that means a performance hit, so better reuse sessions in some way.
My controller provides API for CRUD operations in underlying NH repository and is pushing updates to relevant subscribers when certain records are updated in DB.
Your ideas appreciated :)
I'm using StructureMap to handle dependencies and create a NestedContainer to handle session per request. Don't have to mess with CurrentSessionContext or HttpContext anymore for storing session.
http://structuremap.github.io/the-container/nested-containers/
You could even just create a middleware UnitOfWork if you are using OWIN with WebAPI.
Since XSockets has state is will be bad for your database if you open the connection in the OnOpen event since the connection will remain open as long as the socket is open. Best is to use the repository only in the methods calling the CRUD operations as briefly as possible.
To get the instance of your repository should not be a bottleneck in this case.
I will be happy to review any code you might have.
Regards
Uffe
I'm using StructureMap and I've configured ISession with HybridHttpOrLocalThreadStorage life cycle. New session is created and injected into controllers on per request basis.
Now, the question I have is about disposal. I've read number of articles presenting number of different approaches. Some people were doing it in controllers, some in repositories, some in http modules and others did it in Application_EndRequest() handler. Critique ranged from SRP violations to 'the one creating an object should be responsible for its disposal' to name a few.
So the bottom line is that:
common approach was to manually dispose these sessions - why? I have already configured my container to manage particular object's life cycle. Shouldn't it (i.e. IoC) manage it for me?
out of options available for disposal is handling it in Application_EndRequest() "the best" way of going about it?
For example, this article explains in length one available approach but the article itself is over 2.5 years old. Perhaps new version of StructureMap makes most of that implementation obsolete?
If you are using RavenDB .net client you will be using DocumentStore and DocumentSession. Both of these object do a fair amount of work in the background; local caching to mention one thing. Just to keep things clean and efficient, each session should call session.dispose() when the work is done. documentStore.Dispose() should be called when the application ends.
I am building a web application, and whenever I make a database call I need a session.
I understand creating a session object is very expensive.
I am following the repository pattern here: http://web.archive.org/web/20110503184234/http://blogs.hibernatingrhinos.com/nhibernate/archive/2008/10/08/the-repository-pattern.aspx
He uses something called a UnitOfWork to get the session.
For a web application, shouldn't I be storing the Session in Request.Items collection? So its only created once per request?
Do I really need UofW?
The session IS the unit of work - its basically used to store changes until you flush them to the db. Save a static session factory at startup, and use that to create one session per web request - Request.Items seems a valid place to put the session.
The repository pattern is a wrapper over the unit of work. The repository pattern differs from the UoW pattern in that repo.Save(obj) should save the obj to the db straight away, while the UoW waits for a flush.
My advice would be to skip the repository pattern and use the ISession directly (see http://ayende.com/Blog/archive/2009/04/17/repository-is-the-new-singleton.aspx)
In the case of NHibernate the key class is the SessionFactory, which SessionProvider is taking care of for you (if you implement it like that). Keep the SessionFactory alive, and it handles the sessions for you.
I've also seem people save the SessionFactory in their IoC.
Use this to manage your sessions:
HybridSessionBuilder
It manages and gives you access to a single session that's used across the entire application.
Cleaning up some transactional logic and wondered how other people were handling it.
Ayende's recommendation seems to be to handle transactions at the service boundary. This is a ASP.NET web app though, so it hasn't got a clear cut service boundary, at least not right now.
What do people do?
Create a single transaction per request in a HttpModule and handle commit on EndRequest, rollback on Error?
Create transactions in the actual "services" in the application and handle it multiple places?
Something else?
You can use a IoC Container for your service layer and the container can manage the transaction and the Nibenrate Session.
Your WebApp Controller => call (A) Service Layer => call (B) one or several DAO methods /operations.
The IoC container like Spring.NET will manage te TX scope, by example at (A) and will provide a Session to your DAO in (B). The commit (or rollback) will be handled at the end of the service layer call.
Most people use a session-per-request strategy as stated in your first bullet point. However, I don't believe that the transaction needs to be committed on EndRequest. In many web pages it would be easier to commit the transaction based on user action (e.g. clicking submit) and let EndRequest just handle disposing the ISession.
As far as I can tell, there's no need to create an HttpModule as the same functionality can be created in global.asax: http://forum.hibernate.org/viewtopic.php?t=993041.
I'm developing and application that runs as a Windows service. There are other components which include a few WCF services, a client GUI and so on - but it is the Windows service that access the database.
So, the application is a long-running server, and I'd like to improve its performance and scalability, I was looking to improve data access among other things. I posted in another thread about second-level caching.
This post is about session management for the long-running thread that accesses the database.
Should I be using a thread-static context?
If so, is there any example of how that would be implemented.
Every one around the net who is using NHibernate seem to be heavily focussed on web-application style architectures. There seems to be a great lack of documentation / discussion for non-web app designs.
At the moment, my long running thread does this:
Call 3 or 4 DAO methods
Verify the state of the detached objects returned.
Update the state if needed.
Call a couple of DAO methods to persist the updated instances. (pass in the id of the object and the instance itself - the DAO will retrieve the object from the DB again, and set the updated values and session.SaveOrUpdate() before committing the transaction.
Sleep for 'n' seconds
Repeat all over again!
So, the following is a common pattern we use for each of the DAO methods:
Open session using sessionFactory.OpenSession()
Begin transaction
Do db work. retrieve / update etc
Commit trans
(Rollback in case of exceptions)
Finally always dispose transaction and session.Close()
This happens for every method call to a DAO class.
I suspect this is some sort of an anti-pattern the way we are doing it.
However, I'm not able to find enough direction anywhere as to how we could improve it.
Pls note, while this thread is running in the background, doing its stuff, there are requests coming in from the WCF clients each of which could make 2-3 DAO calls themselves - sometimes querying/updating the same objects the long running thread deals with.
Any ideas / suggestions / pointers to improve our design will be greatly appreciated.
If we can get some good discussion going, we could make this a community wiki, and possbily link to here from http://nhibernate.info
Krishna
There seems to be a great lack of documentation / discussion for non-web app designs.
This has also been my experience. However, the model you are following seems correct to me. You should always open a session, commit changes, then close it again.
This question is a little old now, but another technique would be to use Contextual Sessions rather than creating a new session in each DAO.
In our case, we're thinking of creating the session once per thread (for our multi-threaded win32 service), and make it available to the DAOs using either a property that returns SessionFactory.GetCurrentSession() (using the ThreadContext current session provider, so it's session-per-thread) or via DI (dependency injection - once again using ThreadContext.)
More info on GetCurrentSession and Contextual Sessions here.
You can also flush the session without actually closing it and it achieves the same thing. I do.
We've recently started using an IoC container to manage session lifecycle, as a replacement for the contextual sessions mentioned above. (More details here).
I agree, there aren't many examples for stateful apps.
I'm thinking of doing the following:
Like you I have a windows service hosting a number of WCF services. So the WCF services are the entry points.
Ultimately all my WCF services inherit from AbstractService - which handles a lot of logging and basic DB inserts/updates.
In one of the best NHibernate posts I've seen, a HttpModule does the following:
see http://www.codeproject.com/KB/architecture/NHibernateBestPractices.aspx
private void BeginTransaction(object sender, EventArgs e) {
NHibernateSessionManager.Instance.BeginTransaction();
}
private void CommitAndCloseSession(object sender, EventArgs e) {
try {
NHibernateSessionManager.Instance.CommitTransaction();
}
finally {
NHibernateSessionManager.Instance.CloseSession();
}
}
So perhaps I should do something similar in AbstractService. So effectively I'll end up with a session per service invocation. If you examine the NHib best practices article link above, you'll see that the NHibernateSessionManager should deal with everything else, as long as I open and close the session (AbstractService constructor and destructor).
Just a thought. But I'm experiencing errors because my session seems to be hanging around for too long, and I'm getting the infamous error - NHibernate.AssertionFailure: null id in entry (don't flush the Session after an exception occurs).