2011-01-18 8 views
11

Sto usando 5.1.x JBoss, EJB3.0transazione è alternata Timeout

Ho MDB che ascolta la coda JMS. quando MDB riceve un messaggio, invia un messaggio via TCP ad un modem. volte che pretende molto Modem risposta quando il server è in attesa di una risposta:

 byte[] byteData = receive(is); 

coz smusso impostare il timeout su InputStream.

quindi, grazie al contenitore EJB, il timeout della transazione (che è presente di default) ripristinando l'operazione e quindi un nuovo tentativo eseguito nuovamente.

questo meccanismo di default funziona bene per me, il problema è:

A volte la transazione non scaduta, e dopo tanto tempo ho il seguente msg nella 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 

Qualsiasi idea cosa c'è che non va? e perché a volte funziona e a volte non lo fa?

grazie,

raggio.

risposta

11

JBossAS che utilizza il gestore delle transazioni di Arjuna. Nell'intercettore EJB3 la catena inizierà a srotolare e alla fine colpirà gli intercettori del gestore delle transazioni il cui compito è interrompere la transazione.

  • Per MDB vi può annoté con @ActivationConfigProperty(propertyName="transactionTimeout" value="1500")

  • Per gli altri fagioli si può avere @TransactionTimeout(1500) a livello di classe o livello di metodo.

Quando il gestore delle transazioni rileva che la transazione è scaduto e quindi interrompe dall'interno di thread asincrono (diverso dal filo conduttore del metodo), ma non è mai invia un interrupt al thread attualmente in esecuzione.

Pertanto, il risultato è: richiamato mentre più thread attivi all'interno di esso ... interruzione con 1 thread attivi!

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); 

//--- 

Sarà elencare altri thread attivi anche come riferimento Handler, Finalizer, segnale Dispatcher ecc

+0

Come dovrei gestire la cosa? Voglio che "interrompa" il thread attualmente in esecuzione. 10x – rayman

+0

utilizzare un flag per indicare l'interruzione e in base a ciò, il thread deve interrompere l'attività attualmente in esecuzione se è impostato. –

+0

Sì, ma ancora Si dice che il timeout della transazione non sarà in grado di timeout anche i thread aggiuntivi in ​​esecuzione nel thread stesso. Voglio realizzare questo, come potrei implementarlo? 10x. – rayman