2010-07-29 19 views
2

Mon logiciel utilise plusieurs threads pour faire son travail. Il y a un pipeline qui ressemble à ceci:Dois-je utiliser Hibernate avec cette architecture multithread ou l'abandonner?

 
        +-----------------+ 
        |+-----------------+ 
+------------+  ||+-----------------+  +------------+ 
|   |  |||     |  |   | 
| Get and |  ||| Worker Threads |  | Save  | 
| feed work |--->>|||     |--->>|  Output | 
|   |  ||| Do Work  |  |   | 
+------------+  +||     |  +------------+ 
        +|     | 
        +-----------------+ 

Chaque boîte représente un thread séparé. Les flèches entre elles sont des files d'attente sécurisées pour que les objets "de travail" puissent circuler. Le thread "Get and feed work" extrait le travail en attente de la base de données et le place dans un pool de threads de travail. Ces threads de travail effectuent un certain travail, mettant à jour un indicateur d'état sur l'objet de travail (et le stockant dans la base de données) ainsi que certains objets de sortie. Les objets de sortie sont transmis au thread "Save Output" où ils sont sauvegardés et/ou mis à jour dans la base de données.

Le but de cette architecture est principalement l'efficacité de la mise en file d'attente.

J'ai besoin du thread "Get and Feed Work" pour avoir sa propre session/connexion DB afin qu'il puisse lire en continu depuis la base de données, débloquer et transmettre ces données aux threads de travail.

Chaque thread de travail a également besoin de sa propre connexion/session DB principalement pour mettre à jour sa progression dans la base de données quelle que soit la tâche sur laquelle il travaille. Ces connexions/sessions DB sont toujours des mises à jour peu fréquentes et peu fréquentes. Chaque thread de travail produit quelque chose d'important qui nécessite une insertion dans la base de données. Au lieu que chaque thread de travail fasse son propre insert, il reporte cette responsabilité sur le fil "Save Output". Le thread "Save Output" gagne en efficacité en écrivant en DB par lots - les insertions sont beaucoup plus rapides en lots qu'un à la fois. Je commence à penser que Hibernate n'est peut-être pas approprié pour cette architecture.

Je me retrouve à courir dans beaucoup de problèmes concernant les sessions Hibernate, l'éviction, la fusion, l'effacement, le rinçage, oh mon dieu.

Mon architecture semble stable actuellement mais elle semble aussi extrêmement inefficace. Serait-il préférable d'abandonner Hibernate et d'utiliser directement JDBC?

Répondre

0

sessions Hibernate et les objets chargés de sessions sont pas thread-safe ne peuvent donc pas être accessibles par différents threads simultanément , mais il est bon d'y accéder à partir de fils différents séquentiellement. De la description de votre processus, il ne semble pas y avoir de chevauchement entre les threads, donc vous devriez passer les objets et la session.

Assurez-vous de ne pas utiliser les sessions de fil liées cependant, ne pas utiliser SessionFactory.getCurrentSession()

+0

J'utilise des sessions locales de threads, donc il semble que je devrais me détacher. –

+0

Vous pouvez écrire votre propre classe d'utilitaires locaux de thread et lier la session à l'unité d'exécution lors du passage au thread de travail. L'utilisation d'objets détachés et leur fusion peuvent générer beaucoup de requêtes car Hibernate doit obtenir l'état de la base de données. Un autre inconvénient est que vous perdez la possibilité d'utiliser des transactions. Comme une unité de travail implique 3 sessions (obtenir des données, travailler, enregistrer des données), certaines mises à jour simultanées peuvent glisser entre les deux. – Guillaume

1

Vous pouvez détacher les objets transmis entre sessions ou transmettre uniquement l'ID d'objet.

+0

Y at-il Avantages/inconvénients à chaque méthode? Mon inclination naturelle serait de détacher l'objet comme il laisse un fil et le fusionner quand il arrive au nouveau fil. –