42

私はNHibernateを初めて使用し、セッションを途中で閉じるときにいくつかの問題が発生しました。トランザクションごとにセッションを開くのではなく、セッションを再利用することで、これを一時的に解決しました。ただし、セッションの存続期間を管理するには、必要になるたびにセッションを開くことが推奨されるアプローチであるという印象を受けました。いいえ?

それで; セッションを処理するための推奨される方法は何ですか?彼らの生涯はどうあるべきですか?1セッションのPRトランザクション?すべてを処理する1つのシングルトンセッション?または何?

編集:

私のアプリケーションアーキテクチャは、NHibernate + Fluentを使用して、すべてのデータベース処理を行うサーバー側サービスと通信するデスクトップアプリケーションであることに注意してください。(これが何か違いを生むなら...)

4

5 に答える 5

27

アプリが効果的に機能し、NHibernate が提供する機能 (特にキャッシュと遅延読み込み) を活用できるようにするセッション管理戦略が必要です。

セッションの作成は安価なプロセスであり、事前に RAM や CPU をほとんど必要としないため、セッションの保存や再利用について心配する必要はありません (実際、セッションを再利用すると、厄介で予期しない副作用が発生する可能性があります)。セッション ファクトリはコストがかかるため、アプリの起動時に一度だけビルドする必要があります。

経験則は次のとおりです。セッションの有効期間は、セッションの終了後に永続化されたオブジェクトがスコープ内に留まらないように十分に長くする必要があります。

セッションが終了すると、そのセッションから取得したオブジェクトのすべての変更追跡が停止するため、そのオブジェクトを意図的に新しいセッションに再アタッチしない限り、これらの変更は保存されません。したがって、セッションからフェッチしたオブジェクトが存在する限り、セッションは存在している必要があります。Web アプリでは、これは通常、各要求のセッションを意味します。WinForms では、各フォームのセッション。

あなたの場合、NHibernate の作業を行うサービス (Windows サービスとして実行されていると仮定します) を使用して、消費するデスクトップ アプリからの新しい要求ごとにセッションを作成し、その要求が処理されたときにそれを破棄することを検討することをお勧めします。 . サービスがどのように実行され、デスクトップ アプリがサービスと対話するためにどのようなメカニズムを使用するのか正確にはわかりません (リモーティング? WCF? 従来の SOAP?)。

(この一般的な規則にはいくつかの例外があります。他のコードが参照するが変更されない共有リソースを表す永続化されたオブジェクトのセットがあるとします。これらを app-start で事前にロードし、それ以降は切断したままにしておくことができます。の上。)

このような戦略でパフォーマンスが低下する場合は、データベースとの対話が多すぎて、オブジェクト グラフが複雑になっている可能性があります。この場合、第 2 レベルのキャッシュを見てください。

于 2010-01-06T15:00:53.220 に答える
11

Web アプリでは、リクエストごとに 1 つのセッションが必要です。これにより、セッションの有効期間を完全に制御でき、エラー処理が簡素化されます。

デスクトップ アプリでは、プレゼンター (または必要に応じてフォーム) ごとにセッションを使用することをお勧めします。MSDN マガジンの記事で Ayende を引用すると、次のようになります。

デスクトップ アプリケーションで推奨される方法は、フォームごとにセッションを使用して、アプリケーションの各フォームが独自のセッションを持つようにすることです。各フォームは通常、ユーザーが実行したい個別の作業を表すため、セッションの有効期間をフォームの有効期間に一致させることは、実際には非常にうまく機能します。追加の利点は、アプリケーションでフォームを閉じるとセッションも破棄されるため、メモリ リークの問題がなくなることです。これにより、セッションによって読み込まれたすべてのエンティティが、ガベージ コレクター (GC) による再利用の対象になります。

フォームごとに 1 つのセッションを優先する理由は他にもあります。NHibernate の変更追跡を利用できるため、トランザクションをコミットするとすべての変更がデータベースにフラッシュされます。また、異なるフォーム間に分離バリアを作成するため、他のフォームに表示される他のエンティティへの変更を気にすることなく、単一のエンティティへの変更をコミットできます。

于 2010-01-06T14:23:55.230 に答える
6

セッションは作業単位に対応する必要があります。そのセッションを使用して取得または永続化されたオブジェクトを操作している間、セッションは存続する必要があります。

于 2010-01-06T14:20:15.110 に答える
2

すべての状況に適合する 1 つの答えはありません。Summer of Nhibernateのセッション 13では、この問題の優れた概要が説明されています。

于 2010-01-06T14:21:47.450 に答える
0

NHibernate フレームワークと Microsoft ADO.NET Entity Framework の多くは似ています。これは、ADO.NET EF で ObjectContext ライフラインを制御する方法についての非常に優れた記事です。

http://blogs.msdn.com/alexj/archive/2009/05/07/tip-18-how-to-decide-on-a-lifetime-for-your-objectcontext.aspx

NHibernate セッションにも適用する必要があります。

于 2010-01-06T14:22:13.623 に答える