问题 交易是交替超时


我使用的是jboss 5.1.x,EJB3.0

我有MDB,它监听JMS队列。当MDB收到消息时,它会通过TCP向某个调制解调器发送一个msg。 有时,当服务器等待答案时,调制解调器没有响应:

      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

知道什么是错的吗?为什么有时它会起作用,有时它不起作用?

谢谢,

射线。


12619
2018-01-18 13:23


起源



答案:


使用Arjuna的事务管理器的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);

//---

它将列出其他活动线程,如参考处理程序,终结器,信号调度程序等。


11
2018-01-18 16:45



我该怎么处理?我确实希望它“中断”当前运行的线程。 10倍 - rayman
使用一个标志来指示中断,如果设置了,线程必须停止当前正在执行的任务。 - Nayan Wadekar
是的,但你仍然说事务超时也不能超时自己在线程中运行的其他线程。我想实现这个目标,我该如何实现呢? 10X。 - rayman
为此插入代码可能对您有所帮助。见编辑。 - Nayan Wadekar
好了,谢谢! - rayman


答案:


使用Arjuna的事务管理器的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);

//---

它将列出其他活动线程,如参考处理程序,终结器,信号调度程序等。


11
2018-01-18 16:45



我该怎么处理?我确实希望它“中断”当前运行的线程。 10倍 - rayman
使用一个标志来指示中断,如果设置了,线程必须停止当前正在执行的任务。 - Nayan Wadekar
是的,但你仍然说事务超时也不能超时自己在线程中运行的其他线程。我想实现这个目标,我该如何实现呢? 10X。 - rayman
为此插入代码可能对您有所帮助。见编辑。 - Nayan Wadekar
好了,谢谢! - rayman