2010-03-02 13 views
13

पर बनाई गई है, मैंने एनएचबीरनेट सत्र फ़ैक्टरी कक्षा लिखी है जिसमें स्थिर निबर्ननेट आईएसशन फैक्ट्री है। इसका उपयोग यह सुनिश्चित करने के लिए किया जाता है कि हमारे पास केवल एक सत्र फैक्ट्री है, और पहली बार ओपनसेशन() को कॉल किया जाता है, मैं एक्ट्यूअल सत्र फैक्ट्री बना देता हूं - अगली बार मैं इसका उपयोग करता हूं और उस पर एक सत्र खोलता हूं। कोड इस तरह दिखता है:सुनिश्चित करें कि एनएचबीर्नेट सत्र फ़ैक्टरी केवल

public class NhibernateSessionFactory : INhibernateSessionFactory 
{ 
    private static ISessionFactory _sessionFactory; 

    public ISession OpenSession() 
    { 
     if (_sessionFactory == null) 
     { 
      var cfg = Fluently.Configure(). 
       Database(SQLiteConfiguration.Standard.ShowSql().UsingFile("Foo.db")). 
       Mappings(m => m.FluentMappings.AddFromAssemblyOf<MappingsPersistenceModel>()); 
      _sessionFactory = cfg.BuildSessionFactory(); 
      BuildSchema(cfg); 
     } 
     return _sessionFactory.OpenSession(); 
    } 

    private static void BuildSchema(FluentConfiguration configuration) 
    { 
     var sessionSource = new SessionSource(configuration); 
     var session = sessionSource.CreateSession(); 
     sessionSource.BuildSchema(session);    
    } 
} 

अब मुझे कोई समस्या है। मेरा आवेदन क्लाइंट और सर्वर के बीच विभाजित है। Nhibernate सामान सर्वर की तरफ है। स्टार्टअप पर मेरा क्लाइंट और सर्वर कुछ सेवाओं के माध्यम से डेटाबेस तक पहुंचना चाहता है जो NhibernateSessionFactory का उपयोग करेगा। परिणाम क्लाइंट से अनुरोध आने से पहले _sessionFactory बनाया गया है या नहीं, इस दौड़ की शर्त है। यदि यह नहीं है तो यह असफल हो जाएगा ..

मुझे लगता है कि मुझे निबर्ननेट सत्र कारखाने में कुछ प्रकार की कतार या प्रतीक्षा तंत्र की आवश्यकता है, लेकिन मुझे यकीन नहीं है कि क्या करना है। किसी को भी पहले एक ही समस्या थी? सबसे अच्छा समाधान क्या है?

उत्तर

17

sessionFactory एक थ्रेड-सुरक्षित सिंगलटन होना चाहिए।

जावा में एक सामान्य पैटर्न एक स्थिर प्रारंभकर्ता में sessionFactory बनाने के लिए है। HibernateUtil देखें। आप सी # में भी ऐसा कर सकते हैं।

लॉक या सिंक्रनाइज़ किए गए अनुभागों के उपयोग सहित सिंगलटन को लागू करने के लिए अन्य patterns हैं। यहां मामूली संस्करण है जो आपकी समस्या को हल करना चाहिए यदि मैं इसे सही ढंग से समझ गया।

static readonly object factorylock = new object(); 

public ISession OpenSession() 
{ 
    lock (factorylock) 
    { 
     if (_sessionFactory == null) 
     { 
      var cfg = Fluently.Configure(). 
       Database(SQLiteConfiguration.Standard.ShowSql().UsingFile("Foo.db")). 
       Mappings(m => m.FluentMappings.AddFromAssemblyOf<MappingsPersistenceModel>()); 
      _sessionFactory = cfg.BuildSessionFactory(); 
      BuildSchema(cfg); 
     } 
    } 
    return _sessionFactory.OpenSession(); 
} 
+0

धन्यवाद! उचित लगता है। मैंने बस म्यूटेक्स का उपयोग करके एक समाधान जोड़ा। लेकिन मुझे इसके बजाय ताला का उपयोग करना चाहिए? – stiank81

+0

लेकिन अगर मुझे एक साथ कई डेटाबेस कनेक्शन की आवश्यकता है तो क्या होगा? वर्तमान में मुझे कई सत्र कारखाने बनाने के लिए अन्य कामकाज नहीं पता है ... – JustAMartin

+0

आप इसे नियंत्रकों में कैसे कार्यान्वित करते हैं? – Chazt3n

4

मैं इस जब SessionFactory बनाने एक Mutex का उपयोग कर हल किया। क्या यह उचित दिखता है:

public class NhibernateSessionFactory : INhibernateSessionFactory 
{ 
    private static ISessionFactory _sessionFactory; 
    private static Mutex _mutex = new Mutex(); // <-- Added 

    public ISession OpenSession() 
    { 
     if (_sessionFactory == null) 
     { 
      _mutex.WaitOne();    // <-- Added 
      if (_sessionFactory == null) // <-- Added 
      {        // <-- Added 
       var cfg = Fluently.Configure(). 
        Database(SQLiteConfiguration.Standard.ShowSql().UsingFile("Foo.db")). 
        Mappings(m => m.FluentMappings.AddFromAssemblyOf<MappingsPersistenceModel>()); 
       _sessionFactory = cfg.BuildSessionFactory(); 
       BuildSchema(cfg); 
      }        // <-- Added 
      _mutex.ReleaseMutex();   // <-- Added 

     } 
     return _sessionFactory.OpenSession(); 
    } 

    private static void BuildSchema(FluentConfiguration configuration) 
    { 
     var sessionSource = new SessionSource(configuration); 
     var session = sessionSource.CreateSession(); 
     sessionSource.BuildSchema(session);    
    } 
} 

एक आकर्षण की तरह काम करने लगता है। लेकिन क्या मुझे इसके बजाय ताला का उपयोग करना चाहिए?

+2

हम्म ... "डबल-चेक लॉकिंग" की तरह दिखता है, जो सिंगलटन को लागू करने के लिए अनुशंसित अभ्यास नहीं है (यह पृष्ठ http: // देखें www.yoda.arachsys.com/csharp/singleton.html)। इसके अलावा, एक म्यूटक्स के बजाय एक सादे लॉक का उपयोग किया जा सकता है। – ewernli

+0

धन्यवाद! लगता है जैसे मुझे सादे लॉक के साथ जाना चाहिए। – stiank81

+0

आपको लॉक का उपयोग नहीं करना चाहिए, आपको कम से कम मॉनिटर क्लास का उपयोग करना चाहिए। http://msdn.microsoft.com/en-us/library/x090d6tf.aspx –

संबंधित मुद्दे