0

I created the nhibernate session in Application_start event of global.asax file,the session is being passed to constructors of service methods.

In the service method I am using the session to do CRUD operations, this works fine.However, When multiple requests or parallel transactions occuring nhibernate is throwing some exceptions.After reading forums i came to know that Nhibernate session is not thread safe.How to make it thread safe and let my application (ASP.NET mvc) work with parallel trandsactions?

2 Answers 2

1

Only way to make it thread safe is to create a new session per each request, you could use current_session_context_class property to managed_web in NHibernate config.

In global.asax

    protected void Application_BeginRequest(object sender, EventArgs e)
    {
        var session = SessionFactory.OpenSession();
        CurrentSessionContext.Bind(session);
    }

    protected void Application_EndRequest(object sender, EventArgs e)
    {
        var session = CurrentSessionContext.Unbind(SessionFactory);
        //commit transaction and close the session
    }

now when you want to access the session, you could use,

Global.SessionFactory.GetCurrentSession()

If you are using a DI container, it's usually built into the container,

For example for Autofac (see this question for more information),

containerBuilder.Register(x => {
    return x.Resolve<ISessionFactory>().OpenSession(); 
}).As<ISession>().InstancePerHttpRequest();
Sign up to request clarification or add additional context in comments.

4 Comments

without using dependency injection how can we get session from global.asax to data access layer?
Global.SessionFactory.GetCurrentSession()
if data access layer is in different project? how to access it.
You could reference the project, or you might want to consider using DI
0

Store it in the HttpContext.

Add this to your global.asax

    public static String sessionkey = "current.session";

    public static ISession CurrentSession
    {
        get { return (ISession)HttpContext.Current.Items[sessionkey]; }
        set { HttpContext.Current.Items[sessionkey] = value; }
    }

    protected void Application_BeginRequest()
    {
        CurrentSession = SessionFactory.OpenSession();
    }

    protected void Application_EndRequest()
    {
        if (CurrentSession != null)
            CurrentSession.Dispose();
    }

And here is the component registration

public class SessionInstaller : IWindsorInstaller
{
    public void Install(IWindsorContainer container, IConfigurationStore store)
    {
        container
            .Register(Component.For<ISession>().UsingFactoryMethod(() => MvcApplication.CurrentSession)
            .LifeStyle
            .PerWebRequest);
    }
}

3 Comments

If we store the session in httpcontext, how can we access it from Data access layer project. I am not using Dependency Injection.please advice
you are confusing a couple of things. 1. You can't start the session in Application_Start and use it for every user that comes in. This is why you start the session in Application_BeginRequest. you want to scope the session to the http request. 2. The session doesn't have to be thread safe if you aren't going to update it from multiple threads. In Application_Start, you want to build your SessionFactory.
if you aren't using DI, just pass the MvcApplication.CurrentSession to your controller constructor

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.