Chapter 7. Transaction Manager

Table of Contents

7.1. Overview
7.1.1. Application
7.1.2. JEUS Transaction Manager
7.1.3. Resource Manager
7.2. Server Transaction Manager Configurations
7.2.1. Worker Thread Pool
7.2.2. Timeout
7.2.3. Root Coordinator and Sub Coordinator
7.2.4. Transaction Join
7.3. Client Transaction Configurations
7.3.1. Transaction Manager
7.3.2. Transaction Manager Type
7.3.3. TCP/IP Port of the Transaction Manager
7.3.4. Worker Thread Pool
7.3.5. Timeout
7.4. Transaction Application Programming
7.4.1. Local Transaction
7.4.2. Client-Managed Transaction
7.4.3. Bean Managed Transaction
7.4.4. Container-Managed Transaction
7.4.5. Using a Transaction Manager
7.5. Transaction Recovery
7.5.1. Transaction Recovery Process
7.5.2. Recovery Related Log File
7.5.3. Recovery Related Configuration
7.5.4. Resource Manager Failure
7.6. Transaction Profile Function
7.7. Transaction Communication Problem between Servers with Different IP Bands

This chapter describes the transaction manager and its surrounding elements in JEUS.

7.1. Overview

The JEUS transaction manager provides various forms of transaction services to applications in the Java EE environment. The JEUS transaction manager provides services according to an application's operation requirements and connections to various resource managers. Furthermore, an application can either assign the control of a transaction to the manager or take the control of the transaction itself as needed. The transaction manager plays a central role in the transaction processing tasks working with the resource manager, application, etc.

In enterprise systems, a transaction service is the basic and important service that safely and efficiently processes large scale client requests for resources. Recently, as the types and scale of resource requests have increased, there is a need for the transaction manager to provide a unified interface and operate more safely.

The JEUS transaction manager provides compatibility with Java Transaction Service (JTS) and supports Java Transaction API (JTA). This is to provide a unified interface and functions for a client to use a transaction. For more information, refer to related API or specification documents. Transaction service is provided in many situations (clients and server applications) where an application can be used to support various forms of applications.

To provide stable services, the transaction manager must ensure the integrity of transactions even when a problem occurs. JEUS transaction manager provides transaction recovery functions that can recover transactions under various error conditions.

The following are the three elements that participate in JEUS transaction processing.

  • An application that receives a service

    An application can access various resources through a web container, EJB container, or client container. The application itself can control the transaction by specifying the start and the end of a transaction, or the container's transaction manager can control the transaction.

  • The transaction management function of the application and the transaction manager that provides the transaction management interface.

    The transaction manager is divided into the server transaction manager and the client transaction manager depending on where the application is running. It directly sends a request to prepare and apply a transaction to the actual resource manager.

  • The resource manager (e.g., database) which is affected by the actual transaction.

    The resource manager accepts a request and processes it.

Each component uses JTA (standard API) for transaction processing to communicate with other components.

This section describes each component and its operation method. For basic information about transactions, refer to the related books or materials.

7.1.1. Application

An application uses JEUS transaction manager to perform transaction related tasks on the resource manager.

  • Local transaction

    Transaction tasks that use a single resource manager can be grouped into a single local transaction. An application starts or ends a local transaction by using the resource manager driver.

    By default, JEUS transaction manager is not involved in a local transaction processing. An application can process a task as a global transaction, but when processing a simple transaction task that uses a single resource manager, it is recommended to use a local transaction which is significantly more efficient.

  • Global transaction

    When an application attempts a sequence of transaction tasks using two or more resource managers, the transaction manager can group the tasks into a single global transaction. A global transaction often uses the 2 phase commit protocol to perform transaction batch jobs of the resources in use.

    When the transaction manager commits a transaction, it traces the execution flow of the application and decides to perform either 1 phase commit or 2 phase commit. This decision is made according to the number and type of the resource managers used in the transaction. A JEUS transaction does not support duplicate transactions, and does not allow the mixing of two or more transactions.

  • User-managed transaction

    An application can specify the start and end of a transaction by using the javax.transaction.UserTransaction object. The decision to commit or rollback a transaction is made entirely by an application. However, even when a commit is executed, JEUS transaction manager can still perform a rollback if the resource manager is unable to process the transaction.

    In an EJB, this user managed transaction is called a bean-managed transaction (BMT).

  • Container managed transaction

    In a container managed transaction, the container decides the start and end of a transaction.

    The commit, rollback, etc. of the transaction are decided entirely by the container. This transaction can only be used in an EJB by specifying the transaction attributes (NotSupported, Required, Supports, RequiresNew, Mandatory, Never) according to each bean's method.

Either a local transaction or global transaction can be used depending on how many resource managers an application uses. In addition, the configuration and application programming methods depend on which agent has the authority over the transactions.

7.1.2. JEUS Transaction Manager

JEUS provides two transaction managers, the server transaction manager and client transaction manager.

The server transaction manager provides all functions for managing a global transaction, while the client transaction manager only acts as the proxy of a server transaction.

Server Transaction Manager

The server transaction manager implements all of the Java Transaction API and is used when a server application uses a transaction.

When a global transaction is started, the server transaction manager collects all the information related to the global transaction and proceeds with the tasks acting as the transaction coordinator. Depending on the situation, the role of the server transaction manager consists of the root coordinator and sub coordinator.

[Figure 7.1] Relationship between Root Coordinator and Sub Coordinator

Relationship between Root Coordinator and Sub Coordinator


  • Root coordinator

    The transaction manager that starts the transaction. The manager where the transaction is propagated to becomes the sub coordinator.

  • Sub coordinator

    Receives commands from the root coordinator to perform tasks. The root coordinator takes an active role in managing transactions, and the sub coordinator takes a passive role.

Client Transaction Manager

The client transaction manager operates as the proxy of the server transaction manager.

The server transaction manager that receives the signal from a global transaction becomes the root coordinator and collects and processes all information related to the transaction. To commit the transaction, the transaction manager sends the commit signal to the root coordinator and receives the result of the commit.

7.1.3. Resource Manager

Applications can perform tasks with various resource managers. Connection managers manage connections to the resource manager.

JEUS provides four types of connection managers (JDBC Connection Manager, JMS Connection Manager, WebT Connection Manager, and Connector Manager). Connection managers report transaction related information to the transaction manager for processing a global transaction.

  • JDBC Resource Manager

    Java Database Connectivity (JDBC) defines the connection between databases and applications for Java-based application development. Applications look up and use the JDBC resource manager from the naming server. For more information, refer to "Chapter 4. JNDI Naming Server" and "Chapter 6. DB Connection Pool and JDBC".

  • JMS Resource Manager

    Java Message Service (JMS) is the specification that defines the queue and topic and the API used for accessing the message saved in them. For more information, refer to "JEUS MQ Guide" or the JMS specification.

  • Tmax (WebT) Resource Manager

    Tmax is a TP-monitor developed by TmaxSoft. In JEUS, a bridge called WebT is provided for a transparent two-way service with the Tmax transaction manager. Since WebT supports a two-way call, general EJB clients can run on Tmax, and the same method can be used to call an EJB Bean on JEUS.

  • Java Connector Architecture (JCA) Resource Manager

    As one of the JavaEE specifications, JCA provides an integrated mechanism of the JavaEE compatible platform and various EISs (Enterprise Information System). By using a connector that supports XA Transactions, an application can handle various transaction tasks as a single global transaction. For more information, refer to "JEUS JCA Guide".

7.2. Server Transaction Manager Configurations

This section describes how to configure JEUS transaction manager.

JEUS users can make various selections through the configurations. The configuration items greatly influence JEUS transaction manager's performance and operation. Therefore, the user should be familiarized with each item to set an appropriate value for each.

The transaction manager configurations can be set in WebAdmin or the console tool, and any additional settings can be configured as system properties.

Using WebAdmin

The following describes the process of changing the configurations in WebAdmin.

  1. Select [Servers] from the left menu of WebAdmin to go to the server list search page.

  2. To dynamically change the configuration, click [Lock & Edit]. For more information about the configuration modes in WebAdmin, refer to JEUS WebAdmin Guide".

  3. Select a server on the page to go to the server configuration page. Select the [Basic] > [Tm Config] menu on the server configuration page to go to the Tm Config page.

  4. Change the transaction configuration, and click [OK]. Click [Apply Changes] from the left menu to apply the changes.

7.2.1. Worker Thread Pool

In JEUS transaction manager, a multiple number of worker threads are used to support communication with other transaction managers. The transaction manager uses the system thread pool on the server by default. The thread pool can be configured on a server where transaction and fast processing is important.

  • Common Thread Pool

    If there are not too many but a constant level of transactions that occur and faster processing than other services is required, then use the system thread pool, which is shared by all services on the server.

    The public thread pool can separately assign the thread count that can only be used by the transaction manager, in the 'Reserved Thread Num' item. The number of reserved threads for the transaction manager must be set by considering the size of the entire thread pool to make sure that it doesn't cause problems for other services.

    Note

    Other services can also configure their own threads, but the total number of threads cannot be greater than the thread pool size. When dynamically changing the Reserved Thread Num, (n → m) when n or m is 0, it is processed as pending and thus requires a restart.

  • Dedicated Thread Pool

    When there are a lot of transactions and if the load fluctuates a lot, it is better to create and use a dedicated thread for the transaction manager instead of the system thread. Since the configurations for the thread pool are the same as those of the system thread pool, refer to ???.

As previously described, the system thread pool or dedicated thread pool can be selected for use. However, the pool type cannot be changed during server operation. The server must be restarted to apply the modified pool type. However, with the exception of the dedicated thread pool's queue size, the pool configurations can all be dynamically changed without restarting the server.

Using WebAdmin

The following describes the process of changing a thread pool in WebAdmin. The thread pool configuration can be changed in the lower part of the page. To configure a thread pool, check the Pooling checkbox.

  • Configuring a Common Thread Pool

    Select Pooling checkbox to configure a common thread pool. Then, set the Reserved Thread Num, and then click [OK].

    [Figure 7.2] Configuring a Common Thread Pool in WebAdmin

    Configuring a Common Thread Pool in WebAdmin


  • Configuring a Dedicated Thread Pool

    Select Dedicated to configure a dedicated thread pool. Enter the required items and then click [OK].

    [Figure 7.3] Configuring a Dedicated Thread Pool in WebAdmin

    Configuring a Dedicated Thread Pool in WebAdmin


Using the Console Tool

The following describes how to change a thread pool by using the console tool.

  • Common thread pool configuration

    Execute modify-system-thread-pool to separately assign a number of threads from the thread pool to the transaction manager.

    [DAS]domain1.adminServer>modify-system-thread-pool server1 -service transaction
     -reservednum 10
    Successfully performed the MODIFY operation for the transaction thread pool of the 
    server (server1).
    Check the results using "show-system-thread-pool server1 -service transaction or 
    modify-system-thread-pool server1 -service transaction"
  • Dedicated thread pool configuration

    Execute modify-service-thread-pool to use a dedicated thread for the transaction manager.

    If the dedicated thread pool is configured while using the system thread pool, the server must be restarted to apply the changed configuration. If only the attributes are changed while using the dedicated thread pool, then the configuration can be applied dynamically without restarting the server.

    [DAS]domain1.adminServer>modify-service-thread-pool server1 -service transaction 
    -min 10 -max 20
    Successfully performed the MODIFY operation for The transaction thread pool of the 
    server (server1), but all changes were non-dynamic. They will be applied after 
    restarting.
    Check the results using "show-service-thread-pool server1 -service transaction or 
    modify-service-thread-pool server1 -service transaction"

Note

For more information about the commands, refer to JEUS Reference Book. "4.2.5.2. modify-service-thread-pool".

7.2.2. Timeout

The JEUS transaction manager uses various timeout mechanisms for processing exceptions. The transaction manager can be tuned to be suitable for the application system by adjusting the timeout mechanism. The timeout configuration is static and requires a server restart. The configuration must be set before starting the server or the server must be restarted if it is changed while the server is running.

Using WebAdmin

The following describes how to change the timeout setting in WebAdmin. A multiple number of timeout configurations can be changed from the bottom section of the Tm Config page.

[Figure 7.4] Changing the Timeout Setting in WebAdmin

Changing the Timeout Setting in WebAdmin


The following tables describe the configuration items.

  • Basic information

    ItemDescription
    Active TimeoutTimeout to commit from the start of a global transaction. If the time expires, the transaction is forcibly rolled back. (Default Value: 600000 (10min), Unit: ms)
    Automatic Recovery

    Option to automatically recover indoubt transactions to another server when the current transaction manager fails in a cluster environment. Clustering configuration is required to use this option. The log directory of the failed transaction manager must be accessible from another server.

  • Advanced Options

    ItemDescription
    Prepare TimeoutTimeout for the root coordinator to receive a 'prepare' signal from the sub-coordinator and resource manager. If not received within this time, then the root coordinator rolls back the global transaction. (Default Value: 120000 (2min), Unit: ms)
    Prepared Timeout

    Timeout for the sub-coordinator to wait for a global decision on whether to commit or rollback from the root coordinator.

    If not received within this time, then the sub-coordinator sends another response message for 'prepare' to the root coordinator. If it receives no global decision during the next timeout period, then it rolls back the global transaction. (Default Value: 60000 (1min), Unit: ms)

    Commit TimeoutTimeout for the root coordinator to receive a response (commit or rollback) from the sub-coordinator and resource manager. If not received within this time, then the root coordinator records the global transaction in the "Incompleted List" to indicate that the transaction is incomplete. (Default Value: 240000 (4min), Unit: ms)
    Recovery TimeoutTimeout to receive the recovery information. To recover a transaction, the transaction manager attempts to obtain the transaction information. The transaction is rolled back if another transaction manager does not send the recovery information within this time. (Default Value: 120000 (2min), Unit: ms)
    Incomplete Timeout

    Timeout for an incomplete transaction to recover. To complete the entire transaction processing, the transaction manager maintains a list of failed global transactions. The incomplete global transaction information is used during recovery processing and is kept until the timeout expires.

    Therefore, if the timeout is too short, the recovery information will be deleted more frequently, and the transaction manager won't be able to recover the integrity of the global transaction. As a result, the system administrator must process many tasks in order to recover a global transaction. (Default Value: 86400000(1 day), Unit: ms)

Using the Console Tool

The following describes how to change the timeout setting in the console tool.

The transaction manager's timeout setting can be changed by executing modify-transaction-manager. For more information about the command, refer to JEUS Reference Book. "4.2.13.1. modify-transaction-manager".

[DAS]domain1.adminServer>modify-transaction-manager server1 -activeTimeout 20000
Successfully performed the MODIFY operation for transaction of server (server1), but all changes were non-dynamic. They will be applied after restarting.
Check the results using "show-transaction-manager server1 or modify-transaction-manager server1"

7.2.3. Root Coordinator and Sub Coordinator

The transaction manager is divided into the root coordinator and sub coordinator depending on its role. Since the sub coordinator gets transaction-related information from the root coordinator, it must register itself with the root coordinator and make sure that the root coordinator knows that the sub coordinator exists.

The configuration consists of the following two system properties. The user should set the properties carefully by keeping performance and safety in mind.

  • -Djeus.tm.forcedReg=<true or false>

    Determines when the sub coordinator registers itself with the root coordinator.

    Configuration ValueDescription
    trueSub coordinator immediately registers itself when a transaction is transmitted. (default value)
    falseSub coordinator registers itself when the resource manager connected to the sub coordinator is actually used. If set to false, the communication count between transaction managers can be reduced when there are a lot of EJB calls that do not use the resource manager registered with the sub coordinator.

  • -Djeus.tm.checkReg=<true or false>
    Configuration ValueDescription
    trueWhen the sub coordinator registers itself, it waits for an ACK from the root coordinator. If the ACK doesn't arrive within the time frame, the registration is considered as failed and any pending transactions are rolled back. (default value)
    falseWhen the sub coordinator registers itself, it doesn't wait for an ACK from the root coordinator. Therefore, when the registration fails due to a problem such as a network error, the sub coordinator is not notified of the problem and thus an error occurs during the commit operation.

7.2.4. Transaction Join

JEUS transaction manager joins the transaction resources of the same resource manager. This allows tasks to be performed without creating additional transaction branches and decreases the overhead. However, this method can be a problem in situations such as when Oracle OCI is used like RAC.

To prepare for such problems, set the following option to "true".

-Djeus.tm.disableJoin=true

7.3. Client Transaction Configurations

The client transaction manager is created to allow a client application to start and end global transactions. This section describes the configurations that are related to the client.

Since the client application doesn't use the configurations in domain.xml, it adds the configuration in the application start script by using the system property format.

7.3.1. Transaction Manager

The client transaction manager is initialized when the client application performs a JNDI lookup. However, depending on the client application, there are situations when the transaction manager is not used. To remove any additional overhead that occurs in such situation, the following information is saved in the start script.

-Djeus.tm.not_use=true

7.3.2. Transaction Manager Type

The client transaction manager is only used in the client container. By default, the transaction manager is used in the client, but to use the server transaction manager in the client, add the following setting to the client application script. For information about the difference between the server transaction manager and client transaction manager, refer to

"7.1.2. JEUS Transaction Manager".

-Djeus.tm.version=server

7.3.3. TCP/IP Port of the Transaction Manager

The client transaction manager uses the TCP/IP port to communicate with other transaction managers.

The client transaction manager automatically finds and uses the appropriate port. To manually set the configuration, add the following setting to the client application script.

-Djeus.tm.port=<port number>

7.3.4. Worker Thread Pool

The worker thread pool setting configures the worker thread pool information.

  • Min

    • To configure this value in the client transaction manager to the number of worker threads created in the pool, add the following setting to the client start script.

      -Djeus.tm.tmMin=<number of threads>
  • Max

    • To configure this value in the client transaction manager to the maximum number of threads created in the pool, add the following setting to the client start script.

       -Djeus.tm.tmMax=<number of threads>

7.3.5. Timeout

The following describes how to configure the transaction manager from a client.

  • Active Timeout

    • Timeout to commit from the start of a global transaction. If the time expires, the transaction is forcibly rolled back. (Default Value: 600000 (10min), Unit: ms)

    • Add the following setting to the client application script to configure this value in the client container.

      -Djeus.tm.activeto=<time in milliseconds>
  • Prepare Timeout

    • The root coordinator must receive a 'prepare' signal from the sub coordinator and resource manager within this time. (Default value: 120000 (2min), Unit: ms)

    • If the signal is not received, then the root coordinator rolls back the global transaction.

    • Add the following setting to the client application script to configure this value in the client container.

      -Djeus.tm.preparedto=<time in milliseconds>

  • Prepared Timeout

    • The sub coordinator must receive a global decision on whether to commit or rollback from its root coordinator within this time. (Default value: 60000 (1min), Unit: ms)

    • If not received within this timeout, then the sub-coordinator sends another response message for 'prepare' to the root coordinator. If it receives no global decision during the next timeout period, then it rolls back the global transaction.

    • Add the following setting to the client application script to configure this value in the client container.

      -Djeus.tm.preparedto=<time in milliseconds>

  • Commit Timeout

    • The root coordinator receives a commit or rollback response from the sub coordinator and resource manager within this time. (Default value: 240000 (4min), Unit: ms)

    • If not received within this timeout, then the root coordinator records the global transaction in the "Incompleted List" to indicate that the transaction has not been completed.

    • Add the following setting to the client application script to configure this value in the client container.

      -Djeus.tm.committo=<time in milliseconds>

  • Recovery Timeout

    • Timeout to receive the recovery information. To recover a transaction, the transaction manager attempts to obtain the transaction information. (Default Value: 120000 (2min), Unit: ms)

    • The transaction is rolled back if another transaction manager does not send the recovery information within this time.

    • Add the following setting to the client application script to configure this value in the client container.

      -Djeus.tm.recoveryto=<time in milliseconds>

  • Incomplete Timeout

    • To complete the entire transaction processing, the transaction manager maintains a list of failed global transactions. The incomplete global transaction information is used during recovery processing and is kept until the timeout expires. Therefore, if the timeout is too short, the recovery information will be deleted more frequently, and the transaction manager won't be able to recover the integrity of the global transaction. As a result, the system administrator must process many tasks in order to recover a global transaction. (Default value: 86400000 (1day), Unit: ms)

    • Add the following setting to the client application script to configure this value in the client container.

      -Djeus.tm.incomplete.to=<time in milliseconds>

7.4. Transaction Application Programming

This section describes some JEUS transaction programming examples.

The following are the 4 programming patterns.

  • Local transaction

  • Client-managed transaction

  • Bean-managed transaction

  • Container-managed transaction

Users and application programmers must first specify in what form the application is to run before starting to program. This will allow them to achieve the expected results and easily resolve any problems that may occur later.

An application can manage transaction tasks as a single transaction. A local transaction is used if a single resource manager can process the tasks. Otherwise, a global transaction must be used to manage the transaction.

7.4.1. Local Transaction

Using a local transaction is an effective way to manage the transaction tasks of a single resource manager. Since a local transaction is light and fast, it is used whenever possible. The local transaction has nothing to do with JEUS transaction manager and can use all types of containers.

The following is an example of using a local transaction. Although it is a Java application, some of the code can be used in other Java EE programs such as a servlet or EJB.

[Example 7.1] <<Client.java>>

import javax.naming.*;
import javax.rmi.PortableRemoteObject;
import java.util.*;
import javax.transaction.UserTransaction;
import java.sql.*;
import javax.sql.*;

public class Client {
    private static Connection con;

    private static Connection getConnection() throws
                              NamingException, SQLException {
         // get a JDBC connection
    }

    private static String insertCustomer(String id, String name,
             String phone) throws NamingException, SQLException {
        // insert a product entity given by the arguments to DB
    }

    private static void deleteCustomer(String id) throws
                              NamingException, SQLException {
        // delete a product entity given by the arguments from DB

    }
 
    public static void main(String[] args) {
        try {
          // get a JDBC connection
          con = getConnection();

          // set the autocommit attribute as false
          con.setAutoCommit(false);

          // insert customers
          for (int i=0 ; i<number/2 ; i++) {
              System.out.println("inserting customer id="+i+"c... from Client");
              customers[i] =
                  insertCustomer(i+"c", "Hong Kil Dong "+i, "000-123-1234-"+i);
          }
          System.out.println("completed inserting customers!!");
          con.commit();

          // delete customers
          for (int i=0 ; i<number/2 ; i++) {
             System.out.println(
                 "deleting customerid="+customers[i]+" ... from Client");
             deleteCustomer(customers[i]);
          }
          System.out.println("completed deleting customers!!");
          con.commit();

       } catch (NamingException ne) {
          System.out.println("Naming Exception caught : " + ne.getMessage());
       } catch (SQLException sqle) {
          System.out.println("SQL Exception caught : " + sqle.getMessage());
       } catch(Exception e) {
          try {
             con.rollback();
          } catch (Exception ee) {
             System.out.println("Transaction Rollback error : " + ee.getMessage());
          }
          System.out.println("Error caught : " + e.getMessage());
          e.printStackTrace();
      } finally {
         try {
             if (con!=null) con.close();
         } catch (SQLException se) {}
      }
   }
}


7.4.2. Client-Managed Transaction

A global transaction can be used in an application of a client container (client managed transaction). The client itself manages transactions by using UserTransaction and calls EJB to process the actual task.

The following is an example of this.

Client

Before starting a global transaction, import a javax.transaction.UserTransaction instance by looking up 'java:comp/UserTransaction'. After starting a global transaction by calling 'begin' on the instance, call the EJB bean multiple times. To commit the transaction task on the EJB Bean, call the commit method of the UserTransaction instance to notify that the transaction is complete.

The method terminates if the transaction is successfully committed. If the global transaction is not committed due to a failure, then an exception is thrown in the method. The javax.transaction.RollbackException is thrown by JEUS transaction manager to guarantee that the global transaction is rolled back. There are also other exceptions that are thrown to notify that JEUS transaction manager is attempting to rollback the global transaction due to an unexpected exception. However, not all transaction tasks of the global transaction are completely rolled back. The rollback method of the UserTransaction instance is called directly from the catch query to roll back the global transaction.

Note

Since a standalone client does not include the concept of components, it supports 'java:/UserTransaction' in order to use another name to lookup 'java:comp/UserTransaction' in the standalone client. In practice, either java:comp/UserTransaction or java:/UserTransaction can be used to look up transactions.

[Example 7.2] <<Client.java>>

package umt;

import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.rmi.PortableRemoteObject;
import java.util.*;
import javax.transaction.UserTransaction;

public class Client {
 public static void main(String[] args) {
   UserTransaction tx = null;
   try {
       InitialContext initial = new InitialContext();
       ProductManager productManager =
           (ProductManager)initial.lookup("productmanager");
       System.out.println("");
       System.out.println("< Testing ProductManager EJBBean " +
               "Using User Managed Transaction >>");
       System.out.println("");
       int number = 10;
       String products[] = new String[number];
       tx = (UserTransaction)initial.lookup("java:comp/UserTransaction");
       tx.begin();
       // insert products
       for (int i=0 ; i<number/2 ; i++) {
            System.out.println("inserting product id="+i+"b...");
           // bean call
            products[i] = productManager.insertProduct(i+"b","ball pen", i*10); 
        }
        for (int i=number/2 ; i<number ; i++) {
            System.out.println("inserting product id="+i+"f...");
            products[i] = productManager.insertProduct(i+"f", "fountain pen", (i-number/3)*50);
        }
        System.out.println("completed inserting products!!");
        // delete products
        for (int i=0 ; i<number ; i++) {
           System.out.println("deleting productid="+products[i]+" ...");
           productManager.deleteProduct(products[i]); // bean call
        }
       System.out.println("completed deleting products!!");
       tx.commit();
   } catch (javax.transaction.SystemException se) {
      System.out.println("Transaction System Error caught : " + se.getMessage());
   } catch (javax.transaction.RollbackException re) {
      System.out.println("Transaction Rollback Errorcaught : " + re.getMessage());
   } catch(Exception e) {
      try {
           tx.rollback();
      } catch (Exception ee) {
          System.out.println("Transaction Rollback error : " + ee.getMessage());
      }
            System.out.println("Error caught : " + e.getMessage());
            e.printStackTrace();
      }
  }
 }
}

EJB

The following EJB bean implements a method that executes transaction tasks. To manage global transactions in a client, the transaction type of EJB must be CMT (container-managed). Since the default value is CMT, no configuration is required. To change the configuration, change the TransactionManagerType setting as shown in the following example.

[Example 7.3] <<ProductManagerEJB.java>>

package umt;

import javax.ejb.*;
import javax.annotation.*;

@Stateless
@TransactionManagement(TransactionManagementType.CONTAINER) 
public class ProductManagerEJB implements ProductManager {
    ....

    public String insertProduct(String id, String name, double price) {
        // insert a product entity given by the arguments to DB
    }

    public void deleteProduct(String id) {
        // delete a product entity indicated by the argument from
        // DB
    }
    .....
}



7.4.3. Bean Managed Transaction

A bean managed transaction uses JTA in an application of a web container and EJB container to explicitly mark the boundaries of a global transaction. It is useful when the application needs to fine-tune the global transaction. The application can decide to rollback and commit on its own since client requests can be processed according to the execution order.

The following is an example of an application executing a global transaction in the EJB container.

Client

In a BMT (Bean-Managed Transaction), an EJB bean processes the global transaction area. Hence, a client simply needs to call the method that performs the transaction tasks.

[Example 7.4] <<Client.java>>

package bmt;

import javax.naming.*;
import javax.rmi.PortableRemoteObject;
import java.util.*;

public class Client {
    public static void main(String[] args) {
        try {
            ProductManager productManager;
            .......
            // Getting a reference to an instance of
            // ProductManager EJB bean.
            .......
            productManager.transactionTest();
        } catch(Exception e) {
           e.printStackTrace();
        }
    }
}


EJB

An EJB bean uses javax.transaction.UserTransaction to start a global transaction. It uses javax.ejb.EJBContext (since EJB is a Session Bean in this example, javax.ejb.SessionContext is used) to get a UserTransaction instance. The global transaction begins and commits through a method call.

For an EJB to run as a bean managed transaction, the TransactionManagement must be set to 'TransactionManagementType.BEAN' using an annotation.

[Example 7.5] <<ProductManagerEJB.java>>

package bmt;

import javax.ejb.*;
import javax.naming.*;
import java.sql.*;
import java.util.*;
import javax.annotation.*;
import javax.transaction.UserTransaction;

@Stateless
@TransactionManagement(TransactionManagementType.BEAN) 
public class ProductManagerEJB implements ProductManager {
    @Resource SessionContext ejbContext;   

    public void transactionTest() {
        UserTransaction tx = null;
        try {
          int number = 20;
          String products[] = new String[number];
          tx = ejbContext.getUserTransaction();
          tx.begin();
          // insert products
          for (int i=0 ; i<number/2 ; i++) {
               System.out.println("inserting product id="+i+"b ...");
               products[i] = insertProduct(i+"b", "ball pen", i*10);
           }
           for (int i=number/2 ; i<number ; i++) {
               System.out.println("inserting product id="+i+"f...");
               products[i] = insertProduct(
                       i+"f", "fountain pen", (i-number/3)*50);
           }
           System.out.println("completed inserting products!!");
            // delete products
           for (int i=0 ; i<number ; i++) {
               System.out.println("deleting product id="+products[i]+" ...");
               deleteProduct(products[i]);
           }
           System.out.println("completed deleting products!!");
           tx.commit();
        } catch (javax.transaction.SystemException se) {
            throw new EJBException(
                "Transaction System Error caught : " + se.getMessage());
        } catch (javax.transaction.RollbackException re) {
            throw new EJBException(
                "Transaction Rollback Error caught : " + re.getMessage());
        } catch(Exception e) {
           try {
              tx.rollback();
           } catch (Exception ee) {
              throw new EJBException(
                  "Transaction Rollback error : " + ee.getMessage());
           }
           throw new EJBException("Error caught : " + e.getMessage());
        }
    }

    private String insertProduct(String id, String name, double price) 
        throws NamingException, SQLException {
        // insert a product entity given by the arguments to DB
    }

    private void deleteProduct(String id) throws NamingException,
                                                 SQLException {
        // delete a product entity indicated by the argument from
        // DB
    }
    // some EJB callback methods
}


7.4.4. Container-Managed Transaction

According to the Java EE specification, an application can delegate the demarcation of a global transaction to a container. A Web or EJB container manages the global transactions related to the method. An application can configure the transaction attributes for each method in the configuration file. This is the easiest way to process a global transaction.

The following is an example of a global transaction managed by an EJB container.

Client

In the following example, a server-side EJB container is managing the global transaction tasks of the EJB in a container managed transaction.

[Example 7.6] <<Client.java>>

package bmt;

import javax.naming.*;
import javax.rmi.PortableRemoteObject;
import java.util.*;

public class Client {
    public static void main(String[] args) {
        try {
            ProductManager productManager;
            // getting a reference to an instance of
            // ProductManager EJB bean.
            productManager.transactionTest();
        } catch(Exception e) {
            e.printStackTrace();
        }
    }
}

EJB

The advantage of using a container-managed transaction is that it prevents the developer from implementing transaction-related codes in the business logic.

As long as appropriate attributes are set in the method of an EJB bean, global transaction related tasks are all delegated to the EJB container. In the following example, the transactionTest method does not contain any transaction related codes. To notify the EJB container to run the EJB Bean as a container managed transaction, either set the TransactionManagement Annotation to TransactionManagerType.CONTAINER or don't set it to anything.

[Example 7.7] <<ProductManagerEJB.java>>

package cmt;

import javax.ejb.*;
import javax.naming.*;
import java.sql.*;
import java.util.*;
import javax.annotation.*;

@Stateless
@TransactionManagement(TransactionManagementType.CONTAINER) 
public class ProductManagerEJB implements ProductManager {
    public void transactionTest() {
      try {
          int number = 20;
          String products[] = new String[number];
          // insert products
          for (int i=0 ; i<number/2 ; i++) {
              System.out.println("inserting product id="+i+"b...");
              products[i] = insertProduct(i+"b", "ball pen", i*10);
          }
          for (int i=number/2 ; i<number ; i++) {
          System.out.println("inserting product id="+i+"f...");
          products[i] = insertProduct(i+"f", "fountain pen", (i-number/3)*50);
      }
      System.out.println("completed inserting products!!");
      // delete products
      for (int i=0 ; i<number ; i++) {
        System.out.println("deleting product id="+products[i]+" ...");
        deleteProduct(products[i]);
      }
      System.out.println("completed deleting products!!");
     } catch(Exception e) {
       throw new EJBException("Error caught : " +  e.getMessage());
     }
  }

    private String insertProduct(String id, String name, double price) 
        throws NamingException, SQLException {
        // insert a product entity given by the arguments to DB
    }

    private void deleteProduct(String id) throws NamingException,
                                                 SQLException {
        // delete a product entity indicated by the argument from
        // DB
    }

    // some EJB callback methods
}


7.4.5. Using a Transaction Manager

A transaction manager can be obtained by looking up the name of java:appserver/TransactionManager from the JNDI Context. A transaction manager can start and end a transaction and provide the function that registers an XAResource or gets a transaction object. For more information, refer to Java Transaction API (JTA) specification.

Note

The method for getting a transaction manager or UserTransaction in JEUS is compatible with Glassfish or SunOne Application Server. Therefore, the same server configuration settings can be used when a 3rd-party library like Hibernate is used.

7.5. Transaction Recovery

This section describes how to recover a transaction. Transaction recovery is an important function used for supporting transaction integrity when an unpredictable error occurs.

7.5.1. Transaction Recovery Process

A transaction manager must have a recovery plan for failures that can happen during a transaction. The recovery plan is focused on guaranteeing the integrity of the transactions that were in progress. The recovery plan varies depending on whether the manager is the root coordinator or the sub coordinator, and whether tasks are performed with an external task manager instead of JEUS.

The following shows the recovery process of a transaction manager.

[Figure 7.5] Simplified Transaction Recovery Process

Simplified Transaction Recovery Process

  • 1, 2) When a transaction manager recovers from a failure, the manager gets transaction information from the transaction log.

  • 3) Next, it sends the recover command to a resource manager according to the log information.

  • 4) In response, the resource manager sends the XIDs of incomplete transactions to the manager.

  • 5) The transaction manager sends a commit or rollback command to the resource manager by using the information gathered from the XIDs and logs.

The recovery method differs slightly according to the transaction manager's role, but overall it follows the aforementioned process. A brief description of each element that participates in the recovery and related configurations are described next.

The Recovery Process by Transaction Manager Type

The transaction manager plays a central role in the transaction recovery. The following describes how the recovery method differs according to the role of the transaction manager.

  • Root Coordinator

    When the transaction manager is the root coordinator, it performs operations such as[Figure 7.5].

  • Sub Coordinator

    The sub coordinator is registered like a single resource manager to the root coordinator.

    Since all decisions come from the root coordinator, the sub coordinator only performs up to the task of getting the XIDs for the resource managers and log files that are registered to the sub coordinator. After this, the XIDs are sent to the root coordinator and waits for a decision. When the decision comes from the root coordinator, the information is sent to the resource manager and completes the recovery.

  • Working with an External Transaction Manager

    JEUS transaction manager runs as the root coordinator and an external transaction manager recognizes JEUS as a single resource manager. In this case, JEUS transaction manager performs all tasks other than making the decision. Later, when the external transaction manager sends the recover command and decision, the recovery task is completed accordingly.

Automatic Transaction Recovery

In an automatic transaction recovery, if the current transaction manager shuts down abnormally in a cluster environment, another server's transaction manager automatically recovers any "indoubt" transactions. To properly execute this function, servers must be in a cluster configuration and the server that is executing the recovery must be able to access the transaction log of the failed server.

The following describes the process of configuring the automatic transaction recovery by using WebAdmin or the console tool. This configuration is applied dynamically without restarting the server.

  • Using WebAdmin

    Select [Servers] from the left menu of WebAdmin to go to the server list page. Then, select a server to go to the server configuration page.

    Select [Tm Config] menu on the server configuration page to go to the transaction configuration page. Check the [Automatic Recovery] checkbox on the configuration page, and then click [OK].

    [Figure 7.6] Automatic Transaction Recovery with WebAdmin

    Automatic Transaction Recovery with WebAdmin


  • Using the Console Tool

    Execute modify-transaction-manager in the console tool to turn on the automatic transaction recovery function. For more information about the command, refer to JEUS Reference Book. "4.2.13.1. modify-transaction-manager".

    [DAS]domain1.adminServer>modify-transaction-manager server1 -automaticRecovery true
    Successfully performed the MODIFY operation for transaction of server (server1), but all changes were non-dynamic. They will be applied after restarting.
    Check the results using "show-transaction-manager server1 or modify-transaction-manager server1"

7.5.2. Recovery Related Log File

The following are the two types of log files that are used to recover transactions.

  • The log that contains the transaction history.

  • The log of the XA resource that was used.

The log file is created in a sub directory of 'SERVER_HOME/workspace/mlog' by default. For the path of SERVER_HOME, refer to "1.5. Directory Structure". The log file path can be changed as described in the following.

For example, a public directory can be designated if it is preferable to save a log to a location where many servers can access for automatic recovery. Back up the log and then restart JEUS if a recovery related problem occurs during operation due to a transaction that doesn't need recovery.

The following describes the process of configuring recovery related log files using WebAdmin or the console tool.

  • Using WebAdmin

    Select [Servers] from the left menu of WebAdmin to go to the server list page.

    Select [Tm Config] on the server configuration page to go to the transaction configuration page. Configure the necessary information in the Advanced Options section, and then click [OK].

    [Figure 7.7] Changing the Transaction Log Directory in WebAdmin

    Changing the Transaction Log Directory in WebAdmin


  • Using the console tool

    The transaction log directory can be changed by using the modify-transaction-manager command of the console tool. For more information about the command, refer to JEUS Reference Book. "4.2.13.1. modify-transaction-manager".

    [DAS]domain1.adminServer>modify-transaction-manager server1 -txLogDir /Users/user1/jeus/domain1/tmlogs
    Successfully performed the MODIFY operation for transaction of server (server1) ,but ALL changes were non-dynamic. They will be applied after restarting.
    Check the results using "show-transaction-manager server1 or modify-transaction-manager server1"

7.5.3. Recovery Related Configuration

Recovery related configurations are listed in this section. They must be added to the server's JVM configuration as system properties. For information about how to add each configuration, refer to ????.

Recovery logging can be blocked for when the system administrator is executing recovery or when performance improvement is needed.

-Djeus.tm.noLogging=true

If recovery fails due to a problem, then the transaction manager will attempt to recover the resource again. Recovery executes once every two minutes, and the user can designate the retry count.

Add the following property to the script to set the retry count. (Default Value: 30)

-Djeus.tm.recoveryTrial=<number of trial>

If there is a transaction that needs to be recovered when a server starts, recovery is performed before the server goes into STANDBY. If there's a failed resource during recovery, then recovery is reattempted in the background.

The retry interval can be configured. (Default Value: (120000) 2min)

-Djeus.tm.recoveryInterval=<time in milliseconds>

JEUS cannot boot if a TM log file is deleted and cannot be recovered. If recovery is not needed, JEUS detects the broken file and resets and deletes all TM log files for a successful startup. (Default Value: false)

-Djeus.tm.ignore.broken.log.file=<true or false>

7.5.4. Resource Manager Failure

When the resource manager fails, the system manager uses the console tool to manually perform recovery. This is because JEUS transaction manager cannot find out whether the resource manager is again in a state where it can perform transaction processing.

After resolving the problem with the resource manager, recovery is proceeded by executing the recover-transactions command in the console tool. For more information about using the console tool, refer to JEUS Reference Book. "4.2.13.2. recover-transactions".

7.6. Transaction Profile Function

JEUS transaction manager provides a function that can execute the user's callback at critical points during each transaction. It cannot be used on the client, and can only be used on the server.

This requires the implementation of a profile listener for users inheriting the following interface.

[Example 7.8] <<CoordinatorProfileListener.java>>

package jeus.transaction.profile;

import jeus.transaction.info.TransactionInfo;

public interface CoordinatorProfileListener extends ProfileListener {

    public void beforePrepare( TransactionInfo info );

    public void afterPrepare( jeus.transaction.info.TransactionInfo info );

    public void beforeSetDecision( TransactionInfo info );

    public void afterSetDecision( TransactionInfo info );

    public void beforeCommit( TransactionInfo info );

    public void afterCommit( TransactionInfo info );

    public void beforeOnePhaseCommit( TransactionInfo info );

    public void afterOnePhaseCommit( TransactionInfo info );

    public void beforeRollback( TransactionInfo info );

    public void afterRollback( jeus.transaction.info.TransactionInfo info );

    public void beforeDestroy( TransactionInfo info );

    public void afterDestroy( TransactionInfo info );

    public void beforeActiveTimeout( TransactionInfo info );

    public void afterActiveTimeout( TransactionInfo info );
}                    

[Example 7.9] <<TransactionInfo.java>>

package jeus.transaction.info;

import javax.transaction.xa.Xid;

public interface TransactionInfo {

    public static final int JEUS_SPECIFIC_CURRENT_FORMAT_XID = 303077;
    public static final int UNSPECIFIED_TIME = -1;

    /**
    * Returns this transaction's XID. The returned XID is an XID of  
    * the internal implementation of JEUS and is serializable.
    * Hereafter, when expressing this XID as a string, use XidToString.getXidHexString().
    *
    * @return the TX's XID implementation
    */
    public Xid getXid();

    /**
    * Returns the transaction manager information as a string. Through this information, 
    * the TX's TM server information (ip, port, etc.) can be known.
    *
    * @return the TX's transaction manager information.
    */
    public String getCoordinator();

    /**
    * Returns an external XID for an externally initiated TX. The returned XID is replaced 
    * by an XID of the internal implementation of JEUS and is serializable.
    *
    * @return the TX's XID implementation
    */
    public Xid getExternalXid();

    /**
    * Returns the active timeout setting in ms.
    *
    * @return the active timeout setting of the TX.
    */
    public long getTimeout();

    /**
    * Returns the time elapsed since the start of the TX in ms.
    *
    * @return the elapsed time of the TX.
    */
    public long getElapseSinceBegin();

    /**
    * Returns the TX's status as a string.
    *
    * @return the status value of the TX as a string.
    */
    public String getStatus();

    /**
    * Returns the XAResources enlisted in the TX as a string.
    *
    * @return the XAResources enlisted in the TX.
    */
    public String[] getXaResources();

    /**
    * Returns the thread that started the TX.
    * This information cannot be obtained from where TX is propagted to.
    *
    * @return the thread that started the TX.
    */

    public Thread getBeginThread();
}           

The implemented listener is configured as a system property. A space, semi colon, or comma is used as a separator for multiple listener classes.

-Djeus.tm.profile.classes="test.profile.MyCoordinatorListener1,test.profile.MyCoordinatorListener2"

7.7. Transaction Communication Problem between Servers with Different IP Bands

An IP address is used to connect between JEUS transaction managers for communication. However, communication may not be possible between JEUS transaction managers in the NAT and external environments due to different IP bands.

This can be resolved by setting the property that maps the real IP to a virtual IP.

Refer to 'JEUS_HOME/templates/nat.properties.template' when creating an IP mapping property and configure it as a system property as shown in the following example.

-Djeus.tm.net.address-mapping-properties=<full path of properties file>