Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fluent Nhibernate configuration error in multi thread application

I have created an multi thread application on IIS (ASP.NET MVC), When the threading server started it creates 10 thread and it's execting workitems into the threads.

Usually my application working well, but some time i have got errors and i'm sure that problem is coming from fluent configuration. And I'm sure again i have made some mistake :)

Here is the my SessionFactory Class :

public class NHibernateHelper
{
    private static ISessionFactory sessionFactory;

    /// <summary>
    /// SessionFactory is static because it is expensive to create and is therefore at application scope.
    /// The property exists to provide 'instantiate on first use' behaviour.
    /// </summary>
    private static ISessionFactory SessionFactory
    {
        get
        {
            if (sessionFactory == null)
            {
                sessionFactory = CreateSessionFactory();
            }
            return sessionFactory;
        }
    }


    /// <summary>
    /// CreateSessionFactory
    /// </summary>
    /// <returns></returns>
    private static ISessionFactory CreateSessionFactory()
    {
        IPersistenceConfigurer dbConfigurer = MsSqlConfiguration.MsSql2005
            .ConnectionString("connection string ..")
                            .Cache(c => c
                                .UseQueryCache()
                                .ProviderClass<NoCacheProvider>()
                    ).ShowSql()
                    .CurrentSessionContext<ThreadStaticSessionContext>(); 
                    return Fluently
                            .Configure()
                            .Database(dbConfigurer)
                            .Mappings(mc =>
                            {
                                mc.FluentMappings.Add(typeof(UserMap));
                                mc.FluentMappings.Add(typeof(ApplicationMap));
                                mc.FluentMappings.Add(typeof(SubscriptionsMap));
                            })
                        .BuildSessionFactory();
    }


    public static ISession GetCurrentSession()
    {
        if (!CurrentSessionContext.HasBind(SessionFactory))
        {
            CurrentSessionContext.Bind(SessionFactory.OpenSession());
        }
        return SessionFactory.GetCurrentSession();
    }



    public static void DisposeSession()
    {
        var session = GetCurrentSession();
        session.Close();
        session.Dispose();
    }

    public static void BeginTransaction()
    {
        GetCurrentSession().BeginTransaction();
    }

    public static void CommitTransaction()
    {
        var session = GetCurrentSession();
        if (session.Transaction.IsActive)
            session.Transaction.Commit();
    }

    public static void RollbackTransaction()
    {
        var session = GetCurrentSession();
        if (session.Transaction.IsActive)
            session.Transaction.Rollback();
    }
}

Every thread is calling NHibernateHelper class with this line inside of itself ;

            var myobjectinstance = new ObjectInstance();
            NHibernateHelper.GetCurrentSession().Save( myobjectinstance );

I saw that, when i started server some time it has invoking 300.000 work item for test purpose successfully. But sometime it's giving errors about 2-3 workitem.

The exception is :

[0] = {"An invalid or incomplete configuration was used while creating a SessionFactory. Check PotentialReasons collection, and InnerException for more detail.\r\n\r\n"}

Inner excetion is :

Object reference not set to an instance of an object.

Inner exception stack trace is :

    at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
    at System.Collections.Generic.Dictionary`2.set_Item(TKey key, TValue value)
    at NHibernate.Impl.SessionFactoryObjectFactory.AddInstance(String uid, String name, ISessionFactory instance, IDictionary`2 properties)
    at NHibernate.Impl.SessionFactoryImpl..ctor(Configuration cfg, IMapping mapping, Settings settings, EventListeners listeners)
    at NHibernate.Cfg.Configuration.BuildSessionFactory()
    at FluentNHibernate.Cfg.FluentConfiguration.BuildSessionFactory() 
    in d:\Builds\FluentNH\src\FluentNHibernate\Cfg\FluentConfiguration.cs:line 93

Any suggestion or help are welcome

like image 247
fyasar Avatar asked Mar 09 '10 21:03

fyasar


1 Answers

It looks like the CreateSessionFactory method is called multiple times. The sessionFactory static field access is not synchronized in this method which makes it not thread safe:

private static ISessionFactory SessionFactory
{
    get
    {
        if (sessionFactory == null)
        {
            sessionFactory = CreateSessionFactory();
        }
        return sessionFactory;
    }
}

Make sure to always synchronize access to shared resources in multithreaded applications. There's a common used pattern in this situation called singleton.

like image 176
Darin Dimitrov Avatar answered Sep 23 '22 02:09

Darin Dimitrov