2011-07-25 2 views
1

Nous travaillons sur un service C# Windows utilisant NHibernate qui est supposé traiter un lot d'enregistrements.Multithread UnitOfWork in Nhibernate

Le service doit traiter environ 6000 enregistrements impairs et il faut actuellement environ 3 heures pour les traiter. Il y a beaucoup de db hits encourus et pendant que nous essayons de les minimiser, nous explorons également des options de multithreading pour améliorer la performance.

Nous utilisons le modèle UnitOfWork pour accéder à la session NHibernate.

C'est à peu près comment le service semble:

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

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

      StopUnitOfWork(); 
     } 
    } 

Nous avons pensé à l'aide de la bibliothèque parallèle de tâches pour essayer de traiter ces enregistrements dans des lots (selon la méthode Parallel.Foreach()). D'après ce que j'ai lu à propos de NHibernate, nous devrions fournir à chaque thread une session NHibernate distincte.

Ma question est de savoir comment alimentez-nous ce ..considering le modèle UnitOfWork qui ne permet d'être disponible une session.

Dois-je envisager d'emballer un UnitOfWork autour du traitement d'un seul enregistrement?

Toute aide très appréciée.

Merci

Répondre

4

La meilleure façon est de commencer une nouvelle UnitOfWork pour chaque thread, utilisez une session contextuelle fil statique NHibernate.Context.ThreadStaticSessionContext. Vous devez être conscient des entités mises en cache.

2

La façon la plus simple est d'envelopper chaque traitement d'un enregistrement dans son propre unité de travail, puis exécutez chaque UOW sur son propre fil. Vous devez vous assurer que chaque session UOW & est démarrée, utilisée et terminée sur un seul thread.

Pour obtenir des performances, vous pouvez diviser le lot d'enregistrements dans des lots plus petits, puis envelopper le traitement de ces petits lots en UOWs et les exécuter sur des threads séparés.

En fonction de votre charge de travail à l'aide d'un cache de second niveau (memcached/membase) pourrait considérablement améliorer votre performance. (par exemple, si vous avez besoin de lire des enregistrements de la base de données pour chaque traitement)

Questions connexes