4

ジョブを実行することを目的としたWindowsWebサービスのコンテキストでは、Webアプリケーション用に開発したNHibernateDALを再利用しようとします。

セッション管理には2つのオプションがあり、それぞれに長所と短所があります。

ステートフルセッション

  • すべてを追跡するため、大幅に成長します(L1 /セッションキャッシュ)
  • 注意深く閉じる必要があります。セッションの破棄は、L1キャッシュをクリアするのに十分ではないようです(メモリプロファイラーを使用して気づいたこと)

ステートレスセッション

  • 現在、マッピングの再利用に失敗しています。「lazy=true」で宣言されたすべてのバッグは、次の例外で終了します(セッションが閉じられていない場合でも)。

[...]を初期化しても、役割のコレクションを遅延初期化できませんでした:[...]、セッションまたはセッションが閉じられていません

明らかに、マッピング(Webアプリと共有されている)をlazy = "false"で更新することはできません。これは、パフォーマンスにとって大きな欠点になります。

  • L2キャッシュと対話できない:共有L2キャッシュがデプロイされると、サービスはL2キャッシュデータを無効にして、Webアプリケーションが最新のデータを取得できるようにすることができなくなります。

NHibernateはこれまで優れていることが証明されており、依存性注入用の構造マップを使用して、ステートフルセッションとNHibernateLINQをWebコンテキストで正常に使用できました。

私の質問は次のとおりです。

  • 長時間実行されるスレッドでNHibernateを使用するための良い解決策はありますか?
  • ステートフルセッションを使用したいのですが、メモリリークを回避するにはどうすればよいですか?
4

2 に答える 2

2

問題が解決しました!実際にはいくつかの問題がありました。

1つ目は、インスタンスのスコープとマルチスレッドに関するものでした。

  • スレッドごとに新しいセッションを作成します。
  • スレッドが作業を終了したらすぐに、スレッドに接続されているすべてのインスタンスをクリーンアップします。StructureMapでは、スレッド内で。を使用しますnew HybridLifecycle().FindCache().DisposeAndClear();。これにより、スレッドに接続されているセッションが閉じられ、破棄されます。
  • ライフサイクルがスレッドスコープの場合、StructureMapはThreadStatic変数を使用してオブジェクトキャッシュへの参照を保持します。したがって、トリックはスレッド内でStructureMapのObjectFactoryを呼び出すことです。最初、このアプリケーションでは、メインスレッドが新しいスレッドの作成を担当し、ObjectFactoryを呼び出しました。それは私たちがした大きな間違いであり、彼らの仕事が終わった後、実際にスレッドをきれいにすることができませんでした。

セッションタイプ:

  • インスタンス化されたStateFulセッションが慎重に破棄されるとすぐに、StateLessSessionを使用する必要はありません。私たちの場合、StatelessSessionにはあまりにも多くの欠点があります(キャッシュ管理が主です)

重要な注意:NHibernate NHibernate Session Factoryをインスタンス化するのは1回だけになるように注意してください!

NHibernateインスタンスを注意深く管理すると、メモリリークは発生しません。

于 2012-10-18T07:07:45.190 に答える
0

長時間実行されるプロセスでステートフルセッションを開いたままにしておくことは決して良い考えではありません。

私の提案は、データベース関連のコードを非データベース関連のコードから分離するようにプロセスを再設計して、データベース関連の操作を短期間のセッション内に維持できるようにすることです。

于 2012-10-10T20:22:52.433 に答える