2010-03-09 4 views
5

Stworzyłem aplikację wielowątkową na IIS (ASP.NET MVC), Po uruchomieniu serwera wątków tworzy 10 wątków i wychodzi z workitem do wątków.Błąd konfiguracji Fluktuacji Nhibernate w aplikacji wielowątkowej

Zwykle moja aplikacja działa dobrze, ale jakiś czas mam błędy i jestem pewien, że problem pochodzi z płynnej konfiguracji. I jestem pewien, znowu zrobiłem jakiś błąd :)

Oto moja klasa SessionFactory:

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

Każdy wątek jest wywołanie klasy NHibernateHelper z tej linii wewnątrz siebie;

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

Zobaczyłem, że kiedy uruchomiłem serwer jakiś czas, udało mu się pomyślnie uruchomić 300 000 elementów pracy. Ale czasami daje błędy około 2-3 workitem.

Wyjątkiem jest:

excetion wewnętrzna jest:

Object reference not set to an instance of an object. 

Wewnętrzna ślad stosu jest wyjątek:

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 

Wszelkie sugestie lub pomoc mile widziane

Odpowiedz

7

Wygląda na to, że metoda CreateSessionFactory nazywa się wiele razy. sessionFactory statyczny dostęp pole nie jest zsynchronizowany w tej metodzie, która sprawia, że ​​nie jest bezpieczeństwo wątków:

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

Upewnij się, że zawsze synchronizować dostęp do zasobów udostępnionych w aplikacjach wielowątkowych. W tej sytuacji występuje typowy wzorzec o nazwie singleton.

+0

Darin, dziękuję za odpowiedź, dobrze, ale instancja SessionFactory też jest zbyt ekscytująca dla każdego wątku. Co powinienem zrobić ? Czy masz jakieś sugestie na ten temat? – fyasar

+0

Tak, zsynchronizuj dostęp do niego. –

+0

Niesamowite, pominąłem to :) Dziękuję bardzo za wasze opinie Darin. – fyasar