2012-02-09 12 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; 
        } 
       } 
      } 
    } 

、その後

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;'を実行すると、例外の元のスタックトレースが破棄され、その後、(あまり重要ではない)追加のパフォーマンスヒットが発生し、そのコード行から始まる新しいスタックトレースが生成されます。その面倒な部分は、元のスタックトレースを失ったため、元の例外がどこからスローされたのかを知ることができないことです。 –

答えて

2

nullセッションがある場合はセッションファクトリを構築しています。アプリケーションの起動時には、BuildSessionFactory()に一度だけ電話する必要があります。

あなたがこれを行う

は、一部の人々は法application_startや、あなたのケースでGlobal.asaxの内側SessionFactoryを構築し、あなた次第ですがsessionFactoryの代わりに、あなたのStaticSessionManagerクラスのsessionのための静的プロパティがあります。

あなたのエラーは、セッションファクトリが複数回構築されていることが原因であると思われます。

もう一つのポイントは、一部の人々は、各リクエストの開始時にトランザクション_session.BeginTransaction()を開き、各要求の終わりにcommitrollbackのどちらかということです。これにより、すべての方法で

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

を失う可能性があります。これらはすべて議論の余地がありますが、私のコード全体の99%に対してこの方法を全く問題なく使用しています。

関連する問題