The transaction
statistic can show which classes
are involved in transaction lock contention. Often, this is sufficient to
help the developer already familiar with the application, identify
application changes for reducing the contention. For cases where the code
paths involved in the contention are not already known, the
transactioncontention
statistic can be useful.
Enabling the transactioncontention
statistic
causes the TIBCO StreamBase® Runtime
runtime to collect a stack backtrace each time a
transaction lock encounters contention. The stacks are saved per managed
class name.
![]() | |
The collection of transaction contention statistics is very expensive computationally and should only be used in development or test systems. |
To use transaction contention statistics, enable them with the
epadmin enable statistics
--statistics=transactioncontention
command.
If your application is not already running, start it. This example uses the TransactionContention snippet shown below.
package com.tibco.ep.dtm.snippets.tuning; import com.kabira.platform.Transaction; import com.kabira.platform.annotation.Managed; /** * Simple transaction contention generator * <p> * Note this sample needs to be explicitly stopped. */ public class TransactionContention { /** * Main entry point * @param args Not used */ public static void main(String[] args) { // // Create a managed object to use for // generating transaction lock contention // final MyManaged myManaged = createMyManaged(); // // Create/start a thread which will // transactionally contend for the object. // new MyThread(myManaged).start(); while (true) { // // Contend for the object here // from // the main thread (competing // with the thread started above). // generateContention(myManaged); nap(200); } } private static MyManaged createMyManaged() { return new Transaction("createMyManaged") { MyManaged m_object; @Override protected void run() { m_object = new MyManaged(); } MyManaged create() { execute(); return m_object; } }.create(); } private static void generateContention(final MyManaged myManaged) { new Transaction("generateContention") { @Override protected void run() { writeLockObject(myManaged); } }.execute(); } @Managed private static class MyManaged { } private static void nap(int milliseconds) { try { Thread.sleep(milliseconds); } catch (InterruptedException e) { } } private static class MyThread extends Thread { MyManaged m_object; MyThread(MyManaged myManaged) { m_object = myManaged; } @Override public void run() { while (true) { generateContention(m_object); nap(200); } } } }
After your application has run long enough to generate some
transaction lock contention, stop the data collection with the
epadmin disable statistics
statistics=transactioncontention
command.
Display the collected data with the epadmin display
statistics --statistics=transactioncontention
command.
======== transaction contention report for A ======== 24 occurrences on type com.kabira.snippets.tuning.TransactionContention$MyManaged of stack: com.kabira.platform.Transaction.lockObject(Native Method) com.kabira.platform.Transaction.writeLockObject(Transaction.java:706) com.kabira.snippets.tuning.TransactionContention$2.run(TransactionContention.java:48) com.kabira.platform.Transaction.execute(Transaction.java:484) com.kabira.platform.Transaction.execute(Transaction.java:542) com.kabira.snippets.tuning.TransactionContention.generateContention(TransactionContention.java:43) com.kabira.snippets.tuning.TransactionContention$MyThread.run(TransactionContention.java:84) 57 occurrences on type com.kabira.snippets.tuning.TransactionContention$MyManaged of stack: com.kabira.platform.Transaction.lockObject(Native Method) com.kabira.platform.Transaction.writeLockObject(Transaction.java:706) com.kabira.snippets.tuning.TransactionContention$2.run(TransactionContention.java:48) com.kabira.platform.Transaction.execute(Transaction.java:484) com.kabira.platform.Transaction.execute(Transaction.java:542) com.kabira.snippets.tuning.TransactionContention.generateContention(TransactionContention.java:43) com.kabira.snippets.tuning.TransactionContention.main(TransactionContention.java:16) sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) java.lang.reflect.Method.invoke(Method.java:483) com.intellij.rt.execution.application.AppMain.main(AppMain.java:134) sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) java.lang.reflect.Method.invoke(Method.java:483) com.kabira.platform.MainWrapper.invokeMain(MainWrapper.java:65)
This output shows the two call paths which experienced contention.
The collected data may be cleared with the epadmin clear
statistics --statistics=transactioncontention
command.