2012-02-09 47 views
0

我是Nhibernate的新手,並通過學習來減慢我的工作方式。我試圖實現一個會話管理器類來幫助我獲得我的數據庫調用的會話。以下是它的代碼。有人可以說,這是否在架構上是正確的,並預見到可擴展性或性能的任何問題?nhibernate會話管理器實現

public static class StaticSessionManager 
{ 
    private static ISession _session; 

    public static ISession GetCurrentSession() 
    { 
     if (_session == null) 
      OpenSession(); 

     return _session; 
    } 

    private static void OpenSession() 
    { 
     _session = (new Configuration()).Configure().BuildSessionFactory().OpenSession(); 
    } 
    public static void CloseSession() 
    { 
     if (_session != null) 
     { 
      _session.Close(); 
      _session = null; 
     } 
    } 
} 

,並在我的數據提供者類,我用下面的代碼來獲取數據。

public class GenericDataProvider<T> 
    { 
      NHibernate.ISession _session; 

      public GenericDataProvider() 
      { 
       this._session = StaticSessionManager.GetCurrentSession(); 
      } 

      public T GetById(object id) 
      { 
       using (ITransaction tx = _session.BeginTransaction()) 
       { 
        try 
        { 
         T obj = _session.Get<T>(id); 
         tx.Commit(); 
         return obj; 
        } 
        catch (Exception ex) 
        { 
         tx.Rollback(); 
         StaticSessionManager.CloseSession(); 
         throw ex; 
        } 
       } 
      } 
    } 

然後

public class UserDataProvider : GenericDataProvider<User> 
{ 
    public User GetUserById(Guid uid) 
    { 
     return GetById(uid) 

    } 
} 

UserDataProvider udp = new UserDataProvider(); 
User u = udp.GetUserById(xxxxxx-xxx-xxx); 

最終用途是這東西是正確的嗎?實例化單個頁面中的很多數據提供者會導致問題嗎?

,我也面臨着一個問題,現在,在那裏,如果我同時做多臺機器同一個讀操作,NHibernate的拋出隨機錯誤 - 我認爲這是由於交易。

請指教。

+0

不要使用'throw ex;'那樣的。爲了正確地重新拋出一個異常,使用'throw;'。執行'throw ex;'會導致異常的原始堆棧跟蹤被丟棄,然後(不太重要)會產生額外的性能影響,從該行代碼開始生成新的堆棧跟蹤。令人沮喪的是,你將無法知道原始異常是從哪裏拋出的,因爲你丟失了原始堆棧跟蹤。 – 2012-02-09 19:28:45

回答

2

從我可以看到你正在建設的會話工廠,如果你有一個null會話。在應用程序啓動時,您只應撥打BuildSessionFactory()一次。

如果你這樣做是你,有些人內部建立Global.asax中SessionFactory的方法application_start或你的情況有一個靜態屬性爲sessionFactory,而不是sessionStaticSessionManager類。

我懷疑你的錯誤是由於這樣的事實:你的會話工廠正在建造多次!

另一點是,有些人在每個請求的開始時打開一個交易_session.BeginTransaction(),並且在每個請求結束時打開commitrollback。這給你一個工作單位,這意味着你可以在每個方法上丟失

using (ITransaction tx = _session.BeginTransaction()) 
{ 
... 
} 

。所有這些都是開放性的討論,但我對所有代碼的99%使用這種方法並沒有任何問題。