Chapter 4. Monitoring Transactions 4.1. Configuring Logging for the Transactions Subsystem You can control the amount of information logged about transactions, independent of other logging settings in JBoss EAP. You can configure the logging settings using the management console or the management CLI. Configuring the Transaction Logger Using the Management Console Navigate to the Logging subsystem configuration. In the management console, click the Configuration tab. If you use a managed domain, you must choose the appropriate server profile. Select Subsystems Logging Configuration and click View . Edit the com.arjuna attributes. Select the Categories tab. The com.arjuna entry is already present. Select com.arjuna and click Edit . You can change the log level and choose whether to use parent handlers or not. Log Level: As transactions can produce a lot of logging output, the default logging level is set to WARN so that the server log is not overwhelmed by transaction output. If you need to check transaction processing details, use the TRACE log level so that transaction IDs are shown. Use Parent Handlers: Parent handler indicates whether the logger should send its output to its parent logger. The default behavior is true . Click Save to save the changes. Configuring the Transaction Logger Using the Management CLI Use the following command to set the logging level from the management CLI. For a standalone server, remove the /profile=default from the command. 4.1.1. Enabling the TRACE log level The TRACE logging level adds data to the log so that you can diagnose Jakarta Connectors issues in JBoss EAP. The following procedure shows you how to enable TRACE level logging for the org.jboss.jca , org.jboss.as.connector , and com.arjuna classes. Prerequisites You have installed JBoss EAP. Procedure Open a terminal. Launch the management CLI. Choose one of the following options: In a managed domain, use the following commands to enable the TRACE logging level for the org.jboss.jca , org.jboss.as.connector , and com.arjuna classes: Replace <PROFILE NAME> with your JBoss EAP profile: default , full or full-ha . If you're running JBoss EAP as a standalone server, use the following commands to enable the TRACE logging level for the org.jboss.jca , org.jboss.as.connector , and com.arjuna classes: Optionally, use the following command to enable the TRACE logging level in the console-handler class: The code snippets are added to the appropriate configuration file: 4.1.2. Enabling the Transaction Bridge Logger The transaction bridge is a layer on top of the XTS and is a layer on top of the Jakarta Transactions or JTS components of the Transaction Manager. It interacts with other parts of the JBoss EAP server. You can enable verbose logging of these components that interact with the Transaction Manager for a detailed explanation of the system's operations. The transaction bridge uses the logging subsystem. When running the JBoss EAP server, logging is configured from the logging subsystem configuration in the standalone-xts.xml file. Logging for the transaction bridge is useful for debugging purposes. You can use the following management CLI command to configure the org.jboss.jbossts.txbridge logger to enable the transaction bridge logging: This generates the following XML in the server configuration file: <logger category="org.jboss.jbossts.txbridge"> <level name="ALL" /> </logger> Note Deployment ordering issues may result in the Transaction Manager components becoming active before the logging subsystem is fully configured, including the transaction bridge. In such cases a default logging level gets applied during startup, thereby resulting in detailed debug messages being missed. You can configure the com.arjuna logger to enable verbose logging using the following management CLI command: This generates the following XML in the server configuration file: <logger category="com.arjuna"> <level name="ALL" /> </logger> 4.1.3. Transaction Log Messages You can track the transaction status while keeping the log files readable by using the DEBUG log level for the transaction logger. For detailed debugging, use the TRACE log level. Refer to Configuring Logging for the Transactions Subsystem for information on configuring the transaction logger. Transaction Manager (TM) can generate a lot of logging information when configured to log in the TRACE log level. Following are some of the most commonly-seen messages. This list is not comprehensive, so you may see messages other than these. Table 4.1. Transaction State Change Transaction Begin When a transaction begins, a method Begin of class com.arjuna.ats.arjuna.coordinator.BasicAction is executed and presented in the log with the message BasicAction::Begin() for action-id <transaction uid> . Transaction Commit When a transaction commits, a method Commit of class com.arjuna.ats.arjuna.coordinator.BasicAction is executed and presented in the log with the message BasicAction::Commit() for action-id <transaction uid> . Transaction Rollback When a transaction rolls back, a method Rollback of class com.arjuna.ats.arjuna.coordinator.BasicAction is executed and presented in the log with the message BasicAction::Rollback() for action-id <transaction uid> . Transaction Timeout When a transaction times out, a method doCancellations of com.arjuna.ats.arjuna.coordinator.TransactionReaper is executed and presented in log as Reaper Worker <thread id> attempting to cancel <transaction uid> . You will then see the same thread rolling back the transaction as shown above. 4.1.4. Decoding Transaction Log Files 4.1.4.1. Locating the XID/UID of a Transaction The javax.transaction.TransactionManager interface provides two ways to locate the transaction identifier: You can call the toString method to print complete information about the transaction, including the identifier. Alternatively, you can cast the javax.transaction.Transaction instance to a com.arjuna.ats.jta.transaction.Transaction and then call either the get_uid method, which returns the ArjunaCore Uid representation, or call the getTxId method, which returns the Xid for the global identifier, that is not the branch qualifier. com.arjuna.ats.jta.transaction.Transaction arjunaTM = (com.arjuna.ats.jta.transaction.Transaction)tx.getTransaction(); System.out.println("Transaction UID" +arjunaTM.get_uid()); 4.1.4.2. Finding the Transaction Status and Resources TransactionStatusConnectionManager The TransactionStatusConnectionManager object is used by the recovery modules to retrieve the status of the transaction. It acts like a proxy for TransactionStatusManager objects by maintaining a table of TransactionStatusConnector objects, each of which connects to a TransactionStatusManager object in the application process. You can retrieve the transaction status using the getTransactionStatus method that takes a transaction Uid and, if available, a transaction type as parameters. The process Uid field in the transactions Uid parameter is used to lookup the target TransactionStatusManagerItem host-port pair in the transaction object store. The host-port pair is used to make a TCP connection to the target TransactionStatusManager object by using a TransactionStatusConnector object. The TransactionStatusConnector passes the transaction Uid and the transaction type to the TransactionStatusManager in order to retrieve the status of the transactions. The following code example shows how to retrieve the TransactionStatusConnectionManager and check the transaction status: // Transaction id Uid tx = new Uid(); . . . . TransactionStatusConnectionManager tscm = new TransactionStatusConnectionManager(); // Check if the transaction aborted assertEquals(tscm.getTransactionStatus(tx), ActionStatus.ABORTED); TransactionStatusManager The TransactionStatusManager object acts as an interface for the Recovery Manager to obtain the status of transactions from the running application processes. One TransactionStatusManager per application process is created by the com.arjuna.ats.arjuna.coordinator.TxControl class. A TCP connection is used for communication between the Recovery Manager and TransactionStatusManager . Any free port is used by the TransactionStatusManager by default. However, the port used can be fixed using the following the property: On creation, the TransactionStatusManager obtains a port that is stored with the host in the object store as a TransactionStatusManagerItem . A Listener thread is started which waits for a connection request from the TransactionStatusConnector . When the connection is established, a Connection thread is created that runs the AtomicActionStatusService service. This service accepts a transaction Uid and a transaction type, if available, from the TransactionStatusConnector object. The transaction status is obtained from the local transaction table and returned back to the TransactionStatusConnector object. 4.1.4.3. Viewing the Transaction History By default, the transaction service does not maintain any history about the transactions. However, you can set the CoordinatorEnvironmentBean.enableStatistics property variable to true for the transaction service to maintain information about the number of transactions created and their respective outcomes. You can use the following management CLI command to enable the statistics: You can obtain more detailed transaction statistics programmatically by using the com.arjuna.ats.arjuna.coordinator.TxStats class. Example: TxStats Class public class TxStats { /** * @return the number of transactions (top-level and nested) created so far. */ public static int numberOfTransactions(); /** * @return the number of nested (sub) transactions created so far. * public static int numberOfNestedTransactions(); /** * @return the number of transactions which have terminated with heuristic * outcomes. */ public static int numberOfHeuristics(); /** * @return the number of committed transactions. */ public static int numberOfCommittedTransactions(); /** * @return the total number of transactions which have rolled back. */ public static int numberOfAbortedTransactions(); /** * @return total number of inflight (active) transactions. */ public static int numberOfInflightTransactions (); /** * @return total number of transactions rolled back due to timeout. */ public static int numberOfTimedOutTransactions (); /** * @return the number of transactions rolled back by the application. */ public static int numberOfApplicationRollbacks (); /** * @return number of transactions rolled back by participants. */ public static int numberOfResourceRollbacks (); /** * Print the current information. */ public static void printStatus(java.io.PrintWriter pw); } The com.arjuna.ats.arjuna.coordinator.ActionManager class provides further information about specific active transactions using the getNumberOfInflightTransactions method that returns the list of currently active transactions.

Commands:
/profile=default/subsystem=logging/logger=com.arjuna:write-attribute(name=level,value= VALUE )
/profile=<PROFILE NAME>/subsystem=logging/logger=org.jboss.jca:add(level=TRACE) /profile=<PROFILE NAME>/subsystem=logging/logger=org.jboss.as.connector:add(level=TRACE) /profile=<PROFILE NAME>/subsystem=logging/logger=com.arjuna:write-attribute(name=level,value=TRACE)
/subsystem=logging/logger=org.jboss.jca:add(level=TRACE) /subsystem=logging/logger=org.jboss.as.connector:add(level=TRACE) /subsystem=logging/logger=com.arjuna:write-attribute(name=level,value=TRACE)
/subsystem=logging/console-handler=CONSOLE:write-attribute(name=level,value=TRACE)
<logger category="com.arjuna"> <level name="TRACE"/> </logger> <logger category="org.jboss.jca"> <level name="TRACE"/> </logger> <logger category="org.jboss.as.connector"> <level name="TRACE"/> </logger>
/subsystem=logging/logger=org.jboss.jbossts.txbridge:add(level=ALL)
<logger category="org.jboss.jbossts.txbridge"> <level name="ALL" /> </logger>
/subsystem=logging/logger=com.arjuna:write-attribute(name=level,value=ALL)
<logger category="com.arjuna"> <level name="ALL" /> </logger>
com.arjuna.ats.jta.transaction.Transaction arjunaTM = (com.arjuna.ats.jta.transaction.Transaction)tx.getTransaction(); System.out.println("Transaction UID" +arjunaTM.get_uid());
// Transaction id Uid tx = new Uid(); . . . . TransactionStatusConnectionManager tscm = new TransactionStatusConnectionManager(); // Check if the transaction aborted assertEquals(tscm.getTransactionStatus(tx), ActionStatus.ABORTED);
EAP_HOME /bin/standalone.sh -DRecoveryEnvironmentBean.transactionStatusManagerPort= NETWORK_PORT_NUMBER
/subsystem=transactions:write-attribute(name=enable-statistics,value=true)
public class TxStats { /** * @return the number of transactions (top-level and nested) created so far. */ public static int numberOfTransactions(); /** * @return the number of nested (sub) transactions created so far. * public static int numberOfNestedTransactions(); /** * @return the number of transactions which have terminated with heuristic * outcomes. */ public static int numberOfHeuristics(); /** * @return the number of committed transactions. */ public static int numberOfCommittedTransactions(); /** * @return the total number of transactions which have rolled back. */ public static int numberOfAbortedTransactions(); /** * @return total number of inflight (active) transactions. */ public static int numberOfInflightTransactions (); /** * @return total number of transactions rolled back due to timeout. */ public static int numberOfTimedOutTransactions (); /** * @return the number of transactions rolled back by the application. */ public static int numberOfApplicationRollbacks (); /** * @return number of transactions rolled back by participants. */ public static int numberOfResourceRollbacks (); /** * Print the current information. */ public static void printStatus(java.io.PrintWriter pw); }