2010-03-09 7 views
5

Ich habe eine Multi-Thread-Anwendung auf IIS (ASP.NET MVC) erstellt, Wenn der Threading-Server gestartet wird erstellt 10 Thread und es Arbeitselemente in die Threads.Fluent Nhibernate Konfigurationsfehler in Multithread-Anwendung

Normalerweise funktioniert meine Anwendung gut, aber irgendwann habe ich Fehler und ich bin sicher, dass das Problem von fließenden Konfiguration kommt. Und ich bin sicher, wieder habe ich einige Fehler gemacht :)

Hier ist die meine Session Klasse:

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(); 
    } 
} 

Jeder Thread innerhalb sich NHibernateHelper Klasse mit dieser Linie ruft;

Ich sah, dass, wenn ich Server gestartet habe, es 300.000 Arbeitsaufgaben für Testzwecke erfolgreich aufgerufen hat. Aber manchmal gibt es Fehler über 2-3 Workitem.

Die Ausnahme ist:

Inner excetion ist:

Object reference not set to an instance of an object. 

Ausnahme-Stack-Trace:

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 

Jede Anregung oder Hilfe sind willkommen

Antwort

7

Es sieht so aus, als ob die Methode CreateSessionFactory mehrfach aufgerufen wird. Das sessionFactory statische Feldzugriff ist in diesem Verfahren nicht synchronisiert, die es nicht Thread sicher macht:

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

Achten Sie darauf, immer in Multithreading-Anwendungen den Zugriff auf gemeinsam genutzte Ressourcen zu synchronisieren. Es gibt ein allgemein verwendetes Muster in dieser Situation, das singleton genannt wird.

+0

Vielen Dank für Ihre Antwort, Sie haben Recht, aber SessionFactory Instanz zu außergewöhnlich für jeden Thread. Was soll ich machen ? Hast du irgendeinen Vorschlag dazu? – fyasar

+0

Ja, synchronisieren Sie den Zugriff darauf. –

+0

Super, ich habe das übersprungen :) Vielen Dank für Ihr Feedback Darin. – fyasar