Analyzing Transaction Lock Promotion

Transaction lock promotion can lead to deadlocks. The transaction statistic can show which classes are involved in transaction lock promotion. Often, this is sufficient to help the developer already familiar with the application, identify application changes for removing the promotion locks. For cases where the code paths involved in the contention are not already known, the transactionpromotion statistic can be useful.

Enabling the transactionpromotion statistic causes the TIBCO StreamBase® Runtime runtime to collect a stack backtrace each time a transaction lock is promoted from read to write. The stacks are saved per managed class name.

[Note]

The collection of transaction promotion statistics is very expensive computationally and should only be used in development or test systems.

To use transaction promotion statistics, enable them with the epadmin enable statistics --statistics=transactionpromotion command.

If your application is not already running, start it. This example uses the TransactionPromotion snippet shown below.

package com.tibco.ep.dtm.snippets.tuning;

import com.kabira.platform.Transaction;
import com.kabira.platform.annotation.Managed;

/**
 * Simple transaction promotion generator
 */
public class TransactionPromotion
{
    private static final MyManaged m_myManaged = createObject();

    /**
     * Main entry point
     * @param args Not used
     */
    public static void main(String[] args)
    {
        new Transaction("promotion")
        {
            @Override
            protected void run()
            {
                readLockObject(m_myManaged);
                // Do promotion
                writeLockObject(m_myManaged);
            }
        }.execute();
    }

    private static MyManaged createObject()
    {
        return new Transaction("createObject")
        {
            MyManaged m_object;

            @Override
            protected void run()
            {
                m_object = new MyManaged();
            }

            MyManaged create()
            {
                execute();
                return m_object;
            }

        }.create();
    }

    @Managed
    private static class MyManaged
    {
    }
}

After your application has run stop the data collection with the epadmin disable statistics --statistics=transactionpromotion command.

Display the collected data with the epadmin display statistics --statistics=transactionpromotion command.

======== Transaction Promotion report for A ========

Data gathered between 2015-03-20 10:27:18 PDT and 2015-03-20 10:28:04 PDT.

1 occurrence on type com.kabira.snippets.tuning.TransactionPromotion$MyManaged of stack:

	com.kabira.platform.Transaction.lockObject(Native Method)
	com.kabira.platform.Transaction.writeLockObject(Transaction.java:706)
	com.kabira.snippets.tuning.TransactionPromotion$1.run(TransactionPromotion.java:29)
	com.kabira.platform.Transaction.execute(Transaction.java:484)
	com.kabira.platform.Transaction.execute(Transaction.java:542)
	com.kabira.snippets.tuning.TransactionPromotion.main(TransactionPromotion.java:22)
	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 path where the promotion occurred.

The collected data may be cleared with the epadmin clear statistics --statistics=transactionpromotion command.