2012-02-09 3 views
0

나는 Nhibernate에 익숙하지 않으며 그것을 배우면서 자신감을 잃어 가고있다. 내 db 호출에 대한 세션을 얻을 수 있도록 세션 관리자 클래스를 구현하려고했습니다. 아래 코드는 그 코드입니다. 누군가가 이것이 구조적으로 정확하고 확장 성과 성능에 문제가 없다고 말할 수 있습니까?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; 
        } 
       } 
      } 
    } 

다음 페이지

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

에서

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

    } 
} 

최종 사용이 정확이 무엇인가인가? 단일 페이지에서 많은 데이터 공급자를 인스턴스화하면 문제가 발생합니까?

나는 또한 동시에 여러 컴퓨터에서 동일한 읽기 작업을 수행하는 경우 Nhibernate가 트랜잭션으로 인한 임의의 오류를 throw합니다.

상담하십시오.

+0

이렇게 'throw ex;'를 사용하지 마십시오. 예외를 올바르게 재현하려면'throw;'를 사용하십시오. 'throw ex;'를 실행하면 예외의 원래 스택 추적이 삭제되고 그다지 중요하지 않게 추가 성능이 발생하여 해당 코드 행에서 시작하는 새로운 스택 추적을 생성합니다. 실망스러운 부분은 원본 스택 추적을 잃어 버렸기 때문에 원래 예외가 어디서 던져 졌는지 알 수 없다는 것입니다. –

답변

2

null 세션이있는 경우 세션 팩토리를 작성하는 것으로 볼 수 있습니다. 응용 프로그램이 시작될 때 한 번만 BuildSessionFactory()으로 전화해야합니다. 당신이 당신에게 달려있다 할

, 어떤 사람들은 StaticSessionManager 클래스 sessionFactory 대신 session에 대한 정적 속성이 방법 application_start 또는 귀하의 경우에는 Global.asax에 내부 SessionFactory을 구축 할 수 있습니다.

귀하의 세션 팩터가 여러 번 작성된다는 사실 때문에 귀하의 실수가 의심스러운 것 같습니다!

또 다른 요점은 각 요청이 시작될 때 _session.BeginTransaction() 트랜잭션을 열고 각 요청이 끝날 때 commit 또는 rollback입니다. 이것은 모든 방법에 대해

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

을 잃을 수있는 작업 단위를 제공합니다. 이 모든 것은 논쟁의 여지가 있지만이 코드를 모든 코드의 99 %에 전혀 문제없이 사용합니다.