2

私はNHibernateを初めて使用し、現在のWebサイトに設定するのに苦労しています。この Web サイトは、1 つのデータベース サーバーを備えた複数の Web サーバーで実行されるため、同時実行の問題に直面することになります。この Web サイトには推定 50,000 人ほどのユーザーが登録されており、各ユーザーにはプロフィール ページがあります。このページでは、Facebook と同じように、他のユーザーが別のユーザーを「いいね」することができます。これは、並行性の問題が発生した場合です。

複数の Web サーバーを使用するため、おそらく MemChached プロバイダーを使用して、2 番目のレベルのキャッシュを使用することを考えていました。NHibernate を使用してこのような「いいね」機能を実装する最良の方法は何ですか? 次の3つの選択肢を考えていました。

  1. シンプルな Count() クエリを使用します。テーブル「User_Likes」があり、各行はあるユーザーから別のユーザーへのいいね! を表します。いいねの数を表示するには、単純にデータベースに変換されるユーザーのいいねの数を尋ねますSELECT COUNT(*) FROM USER_LIKES WHERE ID = x。ただし、ユーザーがプロファイル ページにアクセスするたびに、別のユーザーと同様に、いいね! の数を再計算する必要があるため、これには大きなパフォーマンスの低下が伴うと思います。
  2. ユーザー テーブルで追加のNumberOfLikes列を使用し、ユーザーが別のユーザーを好きまたは嫌いなときにこの値を増減します。ただし、これにより同時実行の問題が発生します。単純な for ループを使用して、2 つのサーバーでユーザーを 1000 回いいねしてテストしたところ、データベースの結果は合計で約 1100 いいねでした。それは 900 の違いです。現実的なテストであろうとなかろうと、これはもちろんオプションではありません。さて、解決策として楽観的ロックと悲観的ロックを検討しました (そうですか?) が、現在のリポジトリ パターンは現時点ではこれを使用するのに適していないので、修正する前に知りたいと思います。これが正しい方法である場合。
  3. 2 と同様ですが、カスタム HQL を使用して update ステートメントを自分で記述しUPDATE User SET NumberOfLikes = NumberOfLikes + 1 WHERE id = xます。これにより、データベースで同時実行の問題が発生することはありませんか? ただし、第 2 レベルのキャッシュが原因で、複数のサーバーでデータの不一致が発生するかどうかはわかりません。

だから...ここで本当にアドバイスが必要です。別のオプションはありますか?これは一般的な状況のように感じられ、確かに NHibernate はこれをエレガントな方法でサポートする必要があります。私はNHIbernateを初めて使用するので、明確で詳細な返信が必要であり、高く評価されています:-)ありがとう!

4

2 に答える 2

1

この問題は、より多くの場所で見られると思います。この特定の問題は 3. で解決できますが、同時実行の問題が発生する他の場所が残ります。

悲観的ロックを実装することをお勧めします。これを行う通常の方法は、トランザクションを HTTP リクエスト全体に適用することです。で を使用して、セッションとトランザクションを開始BeginRequestします。Global.asax次に、EndRequestあなたはそれをコミットします。イベントではError、ロールバックを実行してセッションを破棄する代替パスに進みます。

これは、NHibernate を適用する方法として広く受け入れられています。たとえば、http://dotnetslackers.com/articles/aspnet/Configuring-NHibernate-with-ASP-NET.aspxを参照してください。

于 2010-11-22T13:57:58.990 に答える
0

私は3で行きます。この種のアプリケーションでは、一部のページがしばらく古い値を示していても、それほど重要ではないと私は信じています。

IIRC、HQL の更新ではエンティティ キャッシュ エントリが無効にならないため、手動で行う必要がある場合があります。

于 2010-11-23T00:32:39.540 に答える