2011-01-18 3 views
11

J'utilise 5.1.x jboss, EJB3.0Transaction est alternée Timeouts

Je MDB qui écoute file d'attente JMS. Lorsque le MDB prend un message, il envoie un message via TCP à un modem. parfois que modem ne marche pas de réponse lorsque le serveur est en attente d'une réponse:

 byte[] byteData = receive(is); 

coz je ne peux pas le Délai d'exécution sur InputStream. Ainsi, grâce au conteneur EJB, le délai de transaction (qui est là par défaut) annule l'opération, puis une nouvelle tentative est exécutée à nouveau.

ce mécanisme par défaut fonctionne bien pour moi, le problème est:

Parfois, la transaction arrive jamais à expiration, et après longtemps, je reçois le texte suivant msg dans la console:

15:18:22,578 WARN [arjLoggerI18N] [com.arjuna.ats.arjuna.coordinator.TransactionReaper_18] - TransactionReaper::check timeout for TX a6b2232:5f8:4d3591c6:76 in state RUN 
    15:18:22,578 WARN [arjLoggerI18N] [com.arjuna.ats.arjuna.coordinator.BasicAction_58] - Abort of action id a6b2232:5f8:4d3591c6:76 invoked while multiple threads active within it. 
    15:18:22,578 WARN [arjLoggerI18N] [com.arjuna.ats.arjuna.coordinator.CheckedAction_2] - CheckedAction::check - atomic action a6b2232:5f8:4d3591c6:76 aborting with 1 threads active! 
    15:18:22,578 WARN [arjLoggerI18N] [com.arjuna.ats.arjuna.coordinator.TransactionReaper_7] - TransactionReaper::doCancellations worker Thread[Thread-10,5,jboss] successfully canceled TX a6b2232:5f8:4d3591c6:76 

Tous idée quel est le problème? et pourquoi parfois ça marche et parfois ça ne marche pas?

merci,

ray.

Répondre

11

JBossAS qui utilise Arjuna's Transaction Manager. Dans EJB3, la chaîne d'intercepteurs commencerait à se dérouler et finirait par toucher les intercepteurs du gestionnaire de transactions dont le travail consiste à annuler la transaction.

  • Pour BMD vous pouvez annote avec @ActivationConfigProperty(propertyName="transactionTimeout" value="1500")

  • Pour d'autres haricots, vous pouvez avoir @TransactionTimeout(1500) au niveau de la classe ou le niveau de la méthode.

Lorsque le gestionnaire de transactions détecte que la transaction qu'il a expiré et avorte puis à partir d'un fil asynchrone (différent du fil en cours d'exécution dans la méthode), mais il envoie jamais une interruption au fil en cours d'exécution. Résultat: invoqué alors que plusieurs threads sont actifs ... avec 1 thread actif!

Edit:

//--- 

ThreadGroup root = Thread.currentThread().getThreadGroup().getParent(); 

while (root.getParent() != null) 
    root = root.getParent(); 

findAllThread(root,0); 

//--- 

public static findAllThread(ThreadGroup threadGroup, int level){ 

    int actCount = threadGroup.activeCount(); 
    Thread[] threads = new Thread[actCount*2]; 
    actCount = threadGroup.enumerate(threads, false); 


    for (int i=0; i<actCount; i++) { 
     Thread thread = threads[i]; 
     thread.interrupt(); 
    } 

    int groupCount = threadGroup.activeGroupCount(); 
    ThreadGroup[] groups = new ThreadGroup[numGroups*2]; 
    groupCount = threadGroup.enumerate(groups, false); 

    for (int i=0; i<groupCount; i++) 
     findAllThread(groups[i], level+1); 

//--- 

Il liste d'autres threads actifs aussi comme gestionnaire de référence, Finalizer, répartiteur de signaux, etc.

+0

Comment pourrais-je gérer? Je le veux pour 'interrompre' le fil en cours d'exécution. 10x – rayman

+0

utilisez un indicateur pour indiquer une interruption et sur cette base, le thread doit arrêter sa tâche en cours d'exécution s'il est défini. –

+0

Oui, mais encore Vous dites que le délai d'attente de transaction ne sera pas en mesure d'expirer aussi des threads supplémentaires qui s'exécutent dans le thread lui-même. Je veux réaliser ceci, comment pourrais-je l'implémenter? 10x. – rayman

Questions connexes