2012-02-09 48 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%使用这种方法并没有任何问题。