Транзакция чередуется - PullRequest
       44

Транзакция чередуется

11 голосов
/ 18 января 2011

Я использую jboss 5.1.x, EJB3.0

У меня есть MDB, который слушает очередь JMS. когда MDB принимает сообщение, он отправляет сообщение через TCP на какой-либо модем. иногда этот модем не отвечает, когда сервер ожидает ответа:

      byte[] byteData = receive(is);

Потому что я не могу установить тайм-аут на InputStream.

поэтому, благодаря контейнеру EJB, тайм-аут транзакции (который существует по умолчанию) откатывает операцию, а затем повторная попытка выполняется.

у меня этот механизм по умолчанию работает нормально, проблема в следующем:

Иногда транзакция никогда не прекращалась, и по истечении долгого времени я получаю следующее Сообщение в консоли:

  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

Есть идеи, что случилось? и почему иногда это работает, а иногда нет?

спасибо,

луч.

1 Ответ

11 голосов
/ 18 января 2011

JBossAS, использующий Менеджер транзакций Арджуны. В EJB3 цепочка перехватчиков начинает разворачиваться и в конечном итоге попадает на перехватчики диспетчера транзакций, работа которых заключается в прерывании транзакции.

  • Для MDB вы можете обозначить его @ActivationConfigProperty(propertyName="transactionTimeout" value="1500")

  • Для других бобов вы можете иметь @TransactionTimeout(1500) на уровне класса или метода.

Когда диспетчер транзакций обнаруживает, что для транзакции истекло время ожидания, а затем прерывает ее из асинхронного потока (отличается от потока, запущенного в методе), но он никогда не отправляет прерывание в текущий запущенный поток.

Следовательно, в результате: вызывается, когда в нем активно несколько потоков ... прерывается с 1 активным потоком!

Редактировать:

//---

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

//---

В нем будут перечислены другие активные потоки, такие как обработчик ссылок, финализатор, диспетчер сигналов и т. Д.

...