Transaction is alternating Timeouts

rayman picture rayman · Jan 18, 2011 · Viewed 14.4k times · Source

I am using jboss 5.1.x, EJB3.0

I have MDB which listens to JMS queue. when the MDB taking a message, it dispatch a msg via TCP to some modem. sometimes that Modem doesnt response when the server is waiting for an answer:

      byte[] byteData = receive(is);

coz I cant set timeout on InputStream.

so thanks to the EJB container the transaction timeout(which is there by default) rolling back the operation and then a retry executed again.

this mechanism by default works fine for me, the problem is:

Sometimes the transaction never timed out, and after long time I get the following msg in the 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

Any idea what's wrong? and why sometimes it work and sometimes it doesnt?

thanks,

ray.

Answer

Nayan Wadekar picture Nayan Wadekar · Jan 18, 2011

JBossAS that uses the Arjuna's Transaction Manager. In EJB3 interceptor chain would begin to unroll and eventually hit the transaction manager interceptors whose job it is to abort the transaction.

  • For MDB's you can annote it with @ActivationConfigProperty(propertyName="transactionTimeout" value="1500")

  • For other beans you can have @TransactionTimeout(1500) at class level or method level.

When the transaction manager detects that the transaction has timed out and then aborts it from within an asynchronous thread (different from the thread running in method), but it never sends an interrupt to the currently running thread.

Therefore resulting in : invoked while multiple threads active within it ... aborting with 1 threads active!

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

//---

It will list other active threads also like Reference Handler, Finalizer, Signal Dispatcher etc.