2011-07-25 11 views
1

私たちは、レコードのバッチを処理するはずのNHibernateを使用しているc#windowsサービスに取り組んでいます。NhibernateのマルチスレッドUnitOfWork

サービスは、約6000件の奇数レコードを処理する必要があり、これを処理するのに現在約3時間かかります。 dbヒットが多く発生しており、これらを最小限に抑えようとしている間に、パフォーマンスを向上させるためにマルチスレッドオプションも検討しています。

私たちはUnitOfWorkパターンを使ってNHibernateセッションにアクセスしています。

これは、サービスが見え大体方法です:

public class BatchService 
    { 
     public DoWork() 
     { 
      StartUnitOfWork(); 

      foreach (var record in recordsToBeProcessed) 
      { 
       Process(record); 
       // Perform lots of db operations 
      } 

      StopUnitOfWork(); 
     } 
    } 

我々は(Parallel.Foreach()メソッドを使用して)バッチでこれらのレコードを処理しようとするタスク並列ライブラリを使用して考えました。 これまでNHibernateについて読んだことから、各スレッドに別々のNHibernateセッションを提供する必要があります。

私の質問は、これをどのように提供するのですか?1つのセッションだけを利用できるようにするUnitOfWorkパターンがあると思います。

1つのレコードの処理を中心にUnitOfWorkをラッピングする必要がありますか?

ご迷惑をおかけして申し訳ございません。

おかげ

答えて

4

最良の方法は、スレッド静的コンテキストセッションNHibernate.Context.ThreadStaticSessionContextを使用し、各スレッドのための新しいUnitOfWorkのを開始することです。あなたは、分離されたエンティティに気づく必要があります。

2

最も簡単な方法は、レコードの各処理をそれ自身の作業単位にラップして、各UOWを独自のスレッドで実行することです。各UOW &セッションが開始され、使用され、1つのスレッドで完了していることを確認する必要があります。

パフォーマンスを向上させるには、レコードのバッチを小さなバッチで分割し、次にこの小さなバッチの処理をUOWにラップし、別のスレッドで実行することができます。

第2レベルのキャッシュ(memcached/membase)を使用してワークロードに応じて、パフォーマンスが大幅に向上する可能性があります。 (たとえば、処理ごとにdbからレコードを読み取る必要がある場合)

関連する問題