Getting stacktrace for timeout transactions
fekete_kamosh Aug 12, 2011 4:20 PMHi Arjuna guys,
I found that there are sometimes warnings in my server log (JBossAS [6.0.0.Final "Neo"]) like this:
ARJUNA-12117 TransactionReaper::check timeout for TX 0:ffffc0a80102:126a:4e457d9b:c in state RUN
ARJUNA-12095 Abort of action id 0:ffffc0a80102:126a:4e457d9b:c invoked while multiple threads active within it.
ARJUNA-12108 CheckedAction::check - atomic action 0:ffffc0a80102:126a:4e457d9b:c aborting with 1 threads active!
ARJUNA-12121 TransactionReaper::doCancellations worker Thread[Transaction Reaper Worker 0,5,jboss] successfully canceled TX 0:ffffc0a80102:126a:4e457d9b:c
I understand that TransactionReaper checks transaction timeout of enterprise beans that are launched in transaction context due to setting annotation @javax.ejb.TransactionAttribute(TransactionAttributeType.REQUIRED). After timeout rollback is automatically performed. OK.
Anyway I miss information what methods caused timeout and are being rollbacked so that I know where I should maybe increase timeout using @org.jboss.ejb3.annotation.TransactionTimeout annotation.
I found a nice inspiring solution (thank you John Mazzitelli) using interceptor http://svn.rhq-project.org/repos/rhq/trunk/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/common/TransactionInterruptInterceptor.java
http://community.jboss.org/message/365544#365544
http://management-platform.blogspot.com/2008/11/transaction-timeouts-and-ejb3jpa.html
But this solution expects public modifier for method com.arjuna.ats.arjuna.coordinator.BasicAction.setCheckedAction(CheckedAction c).
In fact Arjuna implementation changed slightly since 2008 when this solution was published and the method in version of Arjuna (JBOSSTS_4_14_0_Final), which is included in JBossAS 6.0.0, looks like:
com.arjuna.ats.arjuna.coordinator.BasicAction {
protected final synchronized void setCheckedAction (CheckedAction c)
}
I vote for encapsalution in general but in this case it is cumbersome for me:-(
Enclosing solution I would like to use, please notice setCheckedAction method which is only workaround of protected modifier I vote against.
package cz.test; import java.io.PrintStream; import java.lang.reflect.Method; import java.util.Hashtable; import javax.interceptor.AroundInvoke; import javax.interceptor.InvocationContext; import com.arjuna.ats.arjuna.common.Uid; import com.arjuna.ats.arjuna.coordinator.BasicAction; import com.arjuna.ats.arjuna.coordinator.CheckedAction; /** * Interceptor for checking rollbacked transactions. * Inspired by John Mazzitelli * http://svn.rhq-project.org/repos/rhq/trunk/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/common/TransactionInterruptInterceptor.java */ public class MyCheckedActionInterceptor { @AroundInvoke public Object intercept(InvocationContext ctx) throws Exception { BasicAction currentTx = null; try { currentTx = BasicAction.Current(); if (currentTx != null) { setCheckedAction(currentTx, new MyCheckedAction()); } } catch (Throwable t) { t.printStackTrace(); } return ctx.proceed(); } private static class MyCheckedAction extends com.arjuna.ats.arjuna.coordinator.CheckedAction { public void check(boolean isCommit, Uid actUid, Hashtable list) { super.check(isCommit, actUid, list); // Show stack trace for (Object thread : list.values()) { if (thread instanceof Thread) { printStackTrace(System.err, ((Thread) thread).getStackTrace()); } } } private void printStackTrace(PrintStream s, StackTraceElement[] stackTrace) { synchronized (s) { s.println(this + " stack trace:"); StackTraceElement[] trace = stackTrace; for (int i = 0; i < trace.length; i++) { if (trace[i].getClassName().startsWith("cz.test")) { s.println("\tat " + trace[i]); } } } } } // I do not like this workaround to bypass protected modifier private void setCheckedAction(BasicAction basicAction, CheckedAction checkedAction) { try { Method setCheckedActionMethod = BasicAction.class.getDeclaredMethod("setCheckedAction", new Class[]{CheckedAction.class}); setCheckedActionMethod.setAccessible(true); setCheckedActionMethod.invoke(basicAction, checkedAction); } catch (Exception e) { e.printStackTrace(); } } }
If you have any other solution how to get stacktrace of timeout rollbacked transaction, please give me a clue.
Thank you
Fekete Kamosh