Show TOC Start of Content Area

Function documentation Using Component-Managed JTA Transactions  Locate the document in its SAP Library structure

Use

The JTA standard enables you to demarcate transactions programmatically in your application code. With this approach, your component is fully in charge of starting and completing the transaction. Since correct transaction execution is very important for the proper functioning of both the component and the whole application, you should use component-managed transactions carefully, when you are certain that you know the requirements of the relevant Java EE standards.

The component-managed JTA transactions are possible with the javax.transaction.UserTransaction interface. It enables the application component to start and complete transactions. Note that an instance of this interface does not represent a transaction object itself. The interface only provides a way for the application to tell the Transaction Service to start a new transaction for it, and later to commit or roll it back. The Transaction Service is responsible for creating the transaction object itself, which is an instance of javax.transaction.Transaction. The Transaction object is associated to the thread, in which the component methods are invoked. The Transaction Service manages the transaction synchronization and the two-phase commit.

Note

Accessing the AS Java Transaction Manager directly via the javax.transaction.TransactionManager interface is not allowed. Instead, use the javax.transaction.UserTransaction, as mandated by the JTA specification.

The use of the UserTransaction interface is restricted to certain types of application components. You can look up a UserTransaction from the following components:

·        Stateless session bean with bean-managed transaction demarcation

·        Stateful session bean with bean-managed transaction demarcation

·        Message-driven bean with bean-managed transaction demarcation

·        Servlet

·        Java ServerPages (JSP)

You cannot use component-managed transactions with:

·        Session beans with container-managed transaction demarcation

·        Java clients

The interface provides the following methods:

·        begin() – demarcates the beginning of the transaction

·        commit() – demarcates the end of the transaction, and the modified data is stored in the database

·        getStatus() – obtains the status of the transaction; JTA defines the following transaction status types:

¡        STATUS_ACTIVE – a transaction is running

¡        STATUS_COMMITTED – the transaction has committed

¡        STATUS_COMMITTING – the transaction is currently committing

¡        STATUS_MARKED_ROLLBACK – the transaction has been set for rollback

¡        STATUS_NO_TRANSACTION – there is no active transaction

¡        STATUS_PREPARED – the transaction has prepared to commit (after the first phase of the two-phase commit)

¡        STATUS_PREPARING – the transaction is preparing to commit

¡        STATUS_ROLLEDBACK - the transaction has rolled back

¡        STATUS_ROLLING_BACK – the transaction is currently rolling back

¡        STATUS_UNKNOWN – there is an active transaction but its status cannot be determined

·        rollback() – demarcates the end of the transaction; the modifications made during the transaction are discarded and the data remains unchanged

·        setRollbackOnly() – marks the transaction for rollback

Note

When using component-managed transactions, you can only use UserTransaction.setRollbackOnly(). Invoking javax.ejb.EJBContext.setRollbackOnly() is an illegal operation.

·        setTransactionTimeout() – enables you to set a timeout for the transaction

Note

If you do not call this method in your application, the system uses the default timeout of 24 hours. We recommend that you set a shorter timeout for the transactions you use.

For more information about the UserTransaction interface, refer to the Java EE API documentation at SUN Microsystems official web site.

This graphic is explained in the accompanying text 

http://java.sun.com

Prerequisites

To use component-managed JTA transaction, you must add jta.jar to the build path of the application component.

Activities

To demarcate a component-managed transaction, you must complete the following steps:

...

       1.      Look up the UserTransaction.

In the AS Java the UserTransaction is looked up from the java:comp/ environment without specifying parameters in the initial naming context:

Example

InitialContext ctx = new InitialContext();

UserTransaction ut = null;

ut = (UserTransaction)ctx.lookup("java:comp/UserTransaction");

For session and message-driven beans the UserTransaction is available through their EJBContext:

Example

MessageDrivenContext context;

UserTransaction ut = null;

public void setMessageDrivenContext(MessageDrivenContext context){

      this.context = context;

      ut = context.getUserTransaction();

...

}

Guidelines:

¡        Perform the lookup early in the component’s life cycle – for example, in the setEJBContext() method for enterprise beans, or in the init() method for Web components. This guarantees that you will have a UserTransaction reference when the component needs to start a transaction.

       2.      Look up the connection factory that you will use to get a connection to the underlying data store. For example, the connection factory may be a DataSource, PersistenceManagerFactory, or an instance of javax.resource.cci.ConnectionFactory.

Example

InitialContext ctx = new InitialContext();

DataSource dataSource =(DataSource) ctx.lookup("java:comp/env/PERSISTENCE_EXAMPLE");

Guidelines:

¡        Look up the connection factory early in the component’s life cycle. Typically, you can do that in the same method where you look up the UserTransaction.

       3.      Start a transaction by invoking UserTransaction.begin(), and get a connection from the connection factory by calling its getConnection() method.

Guidelines:

¡        Call these methods before entering the methods that actually access the data store. In an enterprise bean, call the methods in the ejbCreate() method. In a Web component, invoke them in the service method, but before you have called any methods that access the database.

Example

protected void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {

      ut.begin();

      dataSource.getConnection();

     

      // Invoke the methods that work with the database

...

}

       4.      Close the connection after you finish working with the data store by invoking connection.close().If you use a JDBC connection, also close the statements before closing the connection.

Guidelines:

¡        If you leave the connection open, the underlying physical connection may not be returned to the connection pool, which leads to resource leaks. In addition, if you do not close the connection handle and leave the used statements open, the connection handle may be re-associated to a different physical connection in the next transaction, and the state of the statements may not be consistent. Therefore, you must always close the statements and the connection before completing the transaction.

       5.      Complete the transaction by calling UserTransaction.commit() or UserTransaction.rollback(). Typically, you should commit the transaction if no errors have occurred, and roll it back otherwise.

Example

try {

   ut.begin();

 

   //perform functionality

   ut.commit();

 

} catch (Exception exc) {

   exc.printStackTrace();

   try {

 

      // check transaction status

      if (ut.getStatus() != Status.STATUS_NO_TRANSACTION) {

 

         // rollback the transaction

         ut.rollback();

      }

   } catch (Exception e) {

      e.printStackTrace();

   }

Guidelines:

¡        When using the component-managed transaction scenario with stateless session beans, you cannot span the transaction through several business methods. For this type of enterprise beans the EJB specification requires the transaction in which a business method is executed to be completed before the method returns. Therefore, component-managed transactions are practically useless for stateless session beans.

Example

A scenario where you can use the component-managed transaction contract is when you access the data store from a stateful session bean, or directly from a Web component. In this case, you can program your application in a way that enables several methods to change the data in a single transaction.

A typical example is a session bean that represents a client session to a shopping cart. The bean uses a single transaction to initialize the cart, add or remove items, and finally confirm the entries, or discard all changes – that is, it either commits or rolls back the transaction. Using bean-managed transactions in this scenario reduces the number of database accesses during the client session, which increases performance. The data is changed only once – that is, when the transaction commits.

End of Content Area