12

私は、Windowsサービスとして実行されるアプリケーションを開発しています。いくつかのWCFサービス、クライアントGUIなどを含む他のコンポーネントがありますが、データベースにアクセスするのはWindowsサービスです。

そのため、このアプリケーションは長時間実行されるサーバーであり、パフォーマンスとスケーラビリティを向上させたいと考えていました。特に、データアクセスの向上を目指していました。第2レベルのキャッシュについて別のスレッドに投稿しました。

この投稿は、データベースにアクセスする長時間実行スレッドのセッション管理に関するものです。スレッド静的コンテキストを使用する必要がありますか?もしそうなら、それがどのように実装されるかの例はありますか?

NHibernateを使用しているネット上のすべての人は、Webアプリケーションスタイルのアーキテクチャに重点を置いているようです。Web以外のアプリの設計に関するドキュメント/ディスカッションが大幅に不足しているようです。

現時点では、私の長時間実行スレッドはこれを行います:

  1. 3つまたは4つのDAOメソッドを呼び出す
  2. 返された分離オブジェクトの状態を確認します。
  3. 必要に応じて状態を更新します。
  4. いくつかのDAOメソッドを呼び出して、更新されたインスタンスを永続化します。(オブジェクトのIDとインスタンス自体を渡します-DAOはDBからオブジェクトを再度取得し、トランザクションをコミットする前に更新された値とsession.SaveOrUpdate()を設定します。
  5. 'n'秒間スリープ
  6. もう一度繰り返してください!

したがって、以下は、各DAOメソッドに使用する一般的なパターンです。

  • sessionFactory.OpenSession()を使用してセッションを開く
  • トランザクションを開始します
  • db作業を行います。取得/更新など
  • トランスをコミットする
  • (例外の場合のロールバック)
  • 最後に、常にトランザクションとセッションを破棄します。Close()

これは、DAOクラスへのすべてのメソッド呼び出しで発生します。これは、私たちが行っているアンチパターンのようなものだと思います。

しかし、どうすればそれを改善できるかについて、どこにも十分な方向性を見つけることができません。

plsは、このスレッドがバックグラウンドで実行されている間、WCFクライアントから要求があり、それぞれが2〜3個のDAO呼び出しを行う可能性があることに注意してください。場合によっては、長時間実行されているスレッドが処理する同じオブジェクトをクエリ/更新します。 。

私たちのデザインを改善するためのアイデア/提案/ポインタは大歓迎です。良い議論ができれば、これをコミュニティwikiにして、http://nhibernate.infoからここにリンクすることもできます

クリシュナ

4

5 に答える 5

7

非 Web アプリの設計に関するドキュメントや議論が大幅に不足しているようです。

これは私の経験でもあります。ただし、あなたがフォローしているモデルは私には正しいようです。常にセッションを開き、変更をコミットしてから再度閉じる必要があります。

于 2008-10-05T08:45:23.773 に答える
1

この質問は少し古いものですが、別の手法として、各 DAO で新しいセッションを作成するのではなく、コンテキスト セッションを使用する方法があります。

この場合、(マルチスレッドの win32 サービス用に) スレッドごとに 1 回セッションを作成し、SessionFactory.GetCurrentSession() を返すプロパティのいずれかを使用して (ThreadContext の現在のセッション プロバイダーを使用して) DAO で使用できるようにすることを考えています。 、つまりスレッドごとのセッションです) または DI 経由 (依存性注入 - もう一度 ThreadContext を使用します。)

GetCurrentSession とコンテキスト セッションの詳細については、こちらをご覧ください

于 2011-03-03T14:25:03.057 に答える
0

上記のコンテキスト セッションの代わりとして、IoC コンテナーを使用してセッション ライフサイクルを管理することを最近開始しました。(詳細はこちら)。

于 2011-05-04T15:03:07.147 に答える
0

実際にセッションを閉じずにセッションをフラッシュすることもでき、同じことが達成されます。そうです。

于 2010-03-11T21:51:44.997 に答える
0

ステートフル アプリの例はあまりありません。私は次のことを考えています:

あなたのように、私はいくつかの WCF サービスをホストする Windows サービスを持っています。したがって、WCF サービスはエントリ ポイントです。最終的に、すべての WCF サービスは AbstractService から継承されます。これは、多くのロギングと基本的な DB の挿入/更新を処理します。

私が見た中で最高の NHibernate の投稿の 1 つで、HttpModule は次のことを行います: http://www.codeproject.com/KB/architecture/NHibernateBestPractices.aspxを参照

private void BeginTransaction(object sender, EventArgs e) {
    NHibernateSessionManager.Instance.BeginTransaction();
}
private void CommitAndCloseSession(object sender, EventArgs e) {
    try {
        NHibernateSessionManager.Instance.CommitTransaction();
    }
    finally {
        NHibernateSessionManager.Instance.CloseSession();
    }
}

したがって、おそらく AbstractService で同様のことを行う必要があります。したがって、実質的には、サービス呼び出しごとに 1 つのセッションになります。上記の NHib のベスト プラクティスに関する記事のリンクを調べると、セッション (AbstractService コンストラクターとデストラクター) を開いたり閉じたりする限り、NHibernateSessionManager が他のすべてを処理する必要があることがわかります。

ちょっとした考え。しかし、セッションが長すぎるように見えるため、エラーが発生し、悪名高いエラー - NHibernate.AssertionFailure: null id in entry (例外が発生した後にセッションをフラッシュしないでください) が発生します。

于 2008-11-27T16:32:42.093 に答える