2011-03-18 2 views
4

나는 Fluent NHibernate를 위해 다음과 같은 SessionFactory를 가지고있다.이 thread-safe를 만드는 방법

은 내가 SessionFactory를 만들 때 사용 된

잘못되었거나 불완전한 구성의 오류를 얻고있다. 동일한 키

아이템의와의 InnerException

이미 첨가되었다.

이 문제는 종종 발생하며 내 응용 프로그램은 대부분 잘 작동합니다.

NHibernate: System.Argument Exception : An item with the same key has already been added을 기반으로 내 클래스가이 오류의 간헐적 인 특성을 설명하는 스레드로부터 안전하지 않다고 생각합니다.

using System; 
using NHibernate; 
using NHibernate.Cache; 
using NHibernate.Cfg; 
using FluentNHibernate.Cfg; 
using FluentNHibernate.Cfg.Db; 
using WSS.Data.Domain; 

namespace WSS.Data { 
    public static class SessionFactory { 
     private static ISessionFactory _factory = null; 
     private static ISessionFactory GetFactory() { 
      if (_factory == null) { 
       NHibernate.Cfg.Configuration config; 
       config = new NHibernate.Cfg.Configuration(); 
       config.Configure(); 
       if (config == null) { 
        throw new InvalidOperationException("NHibernate configuration is null."); 
       } 


       config.AddAssembly("WSS.Data"); 
       _factory = config.BuildSessionFactory(); 
       if (_factory == null) { 
        throw new InvalidOperationException("Call to Configuration.BuildSessionFactory() returned null."); 
       } 
      } 
      return _factory; 

     } 

     private static ISessionFactory GetFluentFactory() { 
      if(_factory == null) { 
       _factory = Fluently.Configure() 
        .Database(MsSqlConfiguration.MsSql2000 
         .ConnectionString(c => c 
          .Is(ConnectionStrings.Auto)) 
         .Cache(c => c 
          .UseQueryCache() 
          .ProviderClass()) 
         .ShowSql()) 
        .Mappings(m => m 
         .FluentMappings.AddFromAssemblyOf()) 
        .BuildSessionFactory(); 
      } 

      return _factory; 
     } 

     public static ISession OpenSession() { 
      ISession session; 
      session = GetFluentFactory().OpenSession(); 
      if (session == null) { 
       throw new InvalidOperationException("Call to factory.OpenSession() returned null."); 
      } 
      return session; 
     } 
    } 
}

답변

5

일반적인 접근 방식은 단일 액세스 만 허용하는 뮤텍스 (공용 메서드에서 가능)를 만드는 것입니다. http://msdn.microsoft.com/en-us/library/system.threading.mutex.aspx

컴파일로 테스트하지,하지만 무언가 같이보기 :

private static Mutex _sessionMutex = new Mutex(); 

    public static ISession OpenSession() { 
     ISession session; 

     _sessionMutex.WaitOne(); 

     session = GetFluentFactory().OpenSession(); 
     if (session == null) { 
      throw new InvalidOperationException("Call to factory.OpenSession() returned null."); 
     } 

     _sessionMutex.ReleaseMutex(); 
     return session; 
    } 
+0

감사합니다, 나는 시도 것을 줄 것이다. – modernzombie

+0

그건 나를 위해 작동하지 않습니다 ... 당신이 무엇을 제안합니까? – IamStalker

+0

@IamStalker : 작동하지 않는 것은 무엇입니까? 문제를 나타내는 코드로 새 질문을 게시하십시오. 작동 할 수있는 다른 방법은 "잠금"을 사용하는 것입니다. 그러나 이는 시스템 전체가 아닌 단일 프로세스 (및 해당 스레드)에 대해서만 작동합니다. –