2011-12-07 5 views
3

私は、複数のスレッドが同時にWebソースからスクレイプしたデータをデータベースに取り込む状況があります。スクレーパは、さまざまなソースから新しいデータを収集するために定期的に実行されます。NHibernateマルチスレッドセッション管理

NHibernateを初めて使用していて、セッションの管理方法が完全にわからないのは初めてです。

各ワーカーが何をするかの例:ウェブソースから

  • スクレイプエンティティA
  • スクレイプAに関連する各エンティティB、およびAは、他のB(すなわちAは多くを持っていることを記録BはAを持っている)

各Bを持続させるには、セッションにはBを作成するためのAへの参照が必要であり、Aはその子のリストにBを追加する必要がある。 AとBの両方が持続されます。

AにはBが多く、BにはCが多いというようなABの親子関係の階層があります。葉レベルでは、Aには何千もの葉の子があるため実用的ではありません(?セッションをこのチェーンの途中まで開いたままにしておきます。

代わりに、チェーンの下にある各親の識別子(セッションとは独立して格納できる)を記録し、子を作成する必要があるたびにこのIDを介して親にロードします。

また、ISessionはシングルスレッドであることを理解していますので、少なくともスレッドごとに1つのセッションが必要になりますが、これを超えて、

いずれかのアイデアをいただければ幸いです。

答えて

0

スレッドごとにセッションを作成し、毎回オブジェクトをロードすることなく関連付けを維持するためにsession.Load<>()を使用します。

var data = GetDataForBs(); 

using (var session = OpenSession()) 
using (var tx = session.BeginTransaction()) 
{ 
    foreach (var item in data) 
    { 
     B = ... // create B 
     B.A = session.Load<A>(data.A_Id); // Creates a proxy without loading A to maintain the association 
     session.save(B); 
    } 
    tx.Commit(); 
} 

各エンティティが独自に住んでいる場合は(カスケーディングを必要といけない)あなたは物事をスピードアップする代わりにStatelessSessionを使用することができます

+0

A StatelessSessionは、私の状況での提案に感謝適切であろう。また、トランザクションを開始してコミットすることはどれくらいの頻度で行うのがよいでしょうか?たとえば、個々のインサートごとにコミットするのか、複数のインサートをグループ化するのでしょうか? –

+0

スピードが必要な場合は、グループ化がより優れています。コミットがスローされた場合(たとえば、繰り返しはできません)に挿入を失いたくない場合は、挿入ごとにコミットしてください – Firo

関連する問題