NHibernate session management in Windows Service applications - nhibernate

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).

Related

Change the connection string dynamically (per request) on Entity Framework 7 / MVC 6

I have a MVC 6 application on which I need to connect to a different database (i.e. physical file but same schema) depending on who is accessing to it.
That is: each customer of the web application will have it's data isolated in an SQL database (on Azure, with different performances, price levels, etc.) but all those databases will share the same relational schema and of course, the Entity Framework context class.
var cadConexion = #"Server=(localdb)\mssqllocaldb;Database=DBforCustomer1;Trusted_Connection=True;";
services.AddEntityFramework().AddSqlServer().AddDbContext<DAL.ContextoBD>(options => options.UseSqlServer(cadConexion));
The problem is that if I register the service this way I've tied it to a concrete database for a concrete customer, and I don't know if I can change latter when the middleware execution starts (this would be a good point as I can know then who is ringing at the door).
I know I can construct the Database Context passing the connection string as a parameter but this would imply that I should be creating the Database Context at runtime (early in the pipeline) for every request adn I don't know if this could be potentially unefficient or a bad practice. Furthermore I think this way I can't register the Database Context as a service for injecting it on my controllers...
What is the correct approach for this? Anybody has a similar configuration working on production?
Thanks in advance
I would have preferred not to answer my own question, but I feel that I must offer guidance to those with a similar problem, after a long and deep research over internet so I can save them a lot of time testing multi-connection scenarios, wich is quite laborious...
I've finally used a (very recent) feature and APIs of Azure called "Elastic Database Tools" wich, to be concise, is a set of tools from Microsoft aimed to address this concrete problem, specially for SaaS (software as a service) scenarios (as mine is).
Here is a good link to start with:
https://azure.microsoft.com/en-us/documentation/articles/sql-database-elastic-scale-get-started/
Good luck with your projects!
First of all, I do not recommend swapping connection strings per request.
But that's not the question. You can do this. You will need to pass your DbContext a new connection string.
.AddDbContext caches the connection string in the dependency injection container, so you cannot use DI to make this scenario work. Instead, you will need to instantiate your DbContext yourself and pass it a new connection string.

XSockets.Net - how to manage NHibernate Session Context

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

Replaying transactions after a deadlock in a Session-Per-Request web environment

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.

Proper session (RavenDB/NHibernate) disposal - IoC and web app

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.

Castle Windsor Interceptor and Unit Of Work

Is Castle Windsor's Inteceptor mechanism considered to be a good/effective way of implementing the Unit of Work pattern?
My project involves Castle Windsor, the NHibernate Facility and of course NHibernate - all used in self-hosted WCF services.
Each service method normally requests from the Windsor container an instance of a helper class into which the WCF call is delegated. The helper class has an ISessionManager constructor argument which Windsor resolves via the NHibernate Facility.
The trouble is, the helper class is doing too much work. It has both logic and data access intermingled which means its difficult (virtually impossible) to test and difficult to read.
What I want is to re-arrange responsibilities
I don't want the WCF helper to know anything about transactions or sessions, so no ISessionManager constructor arg, no references to transactions and no ISession.
In order for the WCF helper to do data access, its going to have to rely on a new helper, dare I call it a DAO? or God forbid a repository, on which will be methods for fetching, querying, and possibly saving domain objects.
The problem with returning NHibernate proxied objects from a DAO is that if the session is closed before the entity is returned, any subsequent attempt to access collections on the domain object from the client code will result in an exception as the session is no longer there to be used to lazily fetch the required data. It's obvious really, but everyone new to NHibernate must hit this issue.
So if DAOs and Repos cant close the session, what does?
What I need is one NHibernate session per WCF service operation call, where several DAOs or Respositories can call OpenSession as much as they like, but they all get the same session, and ideally, any attempt to dispose the session would be ignored unless its the last Dispose. Not sure about the last bit, but maybe DAOs and repos just call ISessionManager.OpenSession and leave it to something else to flush and dispose the session.
I thought maybe I could use an interceptor which takes an ISessionManager, opens a session and starts a transaction, forwards the invocation, then if no exception occurs, commits the transaction and disposes the session, otherwise rolls back the transaction if any exception occurs.
Any thoughts?
So if DAOs and Repos cant close the
session, what does?session, what does?
Services own units of work, not DAOs. They demark units of work.
Spring manages transactions using AOP, so interceptors sound like a good bet for transaction management to me.
As far as sessions go, those are UI concepts, so it ought to be the web or desktop UI controller that opens the session, marshals services to fulfill use cases, and closes the session when it's complete.
Castle.Service.Transactions also ties well together with the rest of the castle stack and allow you to use AOP to handle transactions.
Have a look at v3!
https://github.com/haf/Castle.Services.Transaction
And the wiki there!
I also created a new NHibernate Facility:
https://github.com/haf/Castle.Facilities.NHibernate/wiki/NHibernate-Facility---Quick-Start