2010-03-08 4 views
2

Je dois effectuer un traitement par lots pour automatiser les processus métier. Je dois interroger le répertoire à intervalle régulier pour détecter de nouveaux dossiers et faire le traitement. Pendant le traitement des anciens fichiers, de nouveaux fichiers peuvent entrer. Pour l'instant, j'utilise le planificateur à quartz et la synchronisation des threads pour m'assurer qu'un seul thread puisse traiter les fichiers.meilleure pratique pour l'interrogation d'annuaire

Une partie du code sont:

application context.xml

<bean id="methodInvokingJob" 
    class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"><br/> 
    <property name="targetObject" ref="documentProcessor" /><br/> 
    <property name="targetMethod" value="processDocuments" /><br/> 
</bean> 

DocumentProcessor
.....

public void processDocuments() { 
    LOG.info(Thread.currentThread().getName() + " attempt to run."); 
    if (!processing) { 
    synchronized (this) { 
     try { 
      processing = true; 
      LOG.info(Thread.currentThread().getName() + " is processing"); 
      List<String> xmlDocuments = documentManager.getFileNamesFromFolder(incomingFolderPath);    
      // loop over the files and processed unlock files. 
      for (String xmlDocument : xmlDocuments) { 
       processDocument(xmlDocument); 
      } 
     } 
     finally { 
      processing = false; 
     } 
    } 
    } 
} 

Pour le code actuel, Je dois empêcher d'autres threads de traiter les fichiers quand un thread est en cours de traitement. Est-ce une bonne idée ? ou nous supportons le traitement multi-thread. Dans ce cas, comment puis-je savoir quels fichiers sont en cours de traitement et quels fichiers viennent d'arriver? Toute idée est vraiment appréciée.

+1

vous a tagué cette C#, mais votre code ressemble à Java. Assurez-vous de spécifier la langue et le système d'exploitation appropriés. – Gabe

+0

Il semble que quelqu'un d'autre a mis par erreur la balise C#, donc je l'ai changé en Java. Pourtant, nous devons connaître le système d'exploitation pour donner une réponse utile. – Gabe

+0

Merci gabe, c'est le traitement par lots en Java. Comment pouvez-vous formater le code? –

Répondre

2

Je ferais ce qui suit:

  • Un fil qui obtient vos noms de fichiers et les ajoute à une file d'attente synchronisée.

  • Plusieurs threads pour effectuer la lecture réelle: récupérez un élément de la file synchronisée et traitez-le.

Pour vérifier si un fichier est utilisé, vous pouvez simplement essayer de le renommer/le déplacer.

+0

Nous avons fait quelque chose comme ça. Nous avons également gardé en mémoire cache pour vérifier quels fichiers sont actuellement consommés –

5

je construire avec ces pièces:

  1. Castle Transactions with TxF
  2. FileSystemWatcherJavaVersion
  3. TransactionScope (pas de version java à moins que vous pirater beaucoup)
  4. A lock-free queue * (papier discuter perf Java vs .Net, pourrait être en mesure d'obtenir la source from them for Java) Java lock-based queues

    tel que:

Quand il y a un nouveau fichier, le veilleur de système de fichiers détecte (souvenez-vous de mettre les drapeaux corrects, gérer la condition d'erreur et définissez Enbled < - Vrai et faites attention à doubles), met le chemin du fichier dans la file d'attente.

Vous avez un thread d'application, n threads de travail. Si c'est la seule application, ils tournent - attendent dans la file d'attente, TryDequeue, sinon ils bloquent sur un moniteur while (! Monitor.Enter (has_items));

Lorsqu'un thread de travail obtient un chemin à travers l'opération de suppression de file d'attente, il commence à travailler dessus, et aucun autre thread ne peut plus fonctionner. S'il y a des doubles de sortie (selon votre configuration), vous pouvez alors utiliser une transaction de fichier lorsque vous écrivez le fichier de sortie. Si l'opération Commit échoue, vous savez qu'un autre thread a déjà écrit le fichier de sortie et reprend l'interrogation de la file d'attente.

+0

Merci pour l'info Henrik, toute la bibliothèque mentionnée est complètement nouvelle pour moi mais je dois assurément assurer la transaction donc je vais me pencher sur TxF. Pour l'instant, j'ai l'intention d'utiliser Spring Batch + Spring Integration. Je viens de lire l'introduction et quelques démos mais ils m'ont tous convaincus que c'est la bonne solution pour chasser. –

Questions connexes