SimpleJTA V1 User's Guide

Overview

SimpleJTA provides an implementation of the UserTransaction interface. It also provides pooled Datasource implementations. At present, only Oracle and Derby datasource implementations are provided.

An application wishing to use SimpleJTA needs to perform following simple steps:

Create the transaction log tables

SimpleJTA requires a database to store its transaction log. The transaction log tables can reside in one of the databases that will be involved in transactions, or they can reside in an embedded or network Derby database.

The vendor specific script create_tables.sql can be found in the subdirectory sql/tm in the distribution. Run the appropriate script against the database of your choice. At present, only Oracle and Derby implementations are provided.

In following sections we will refer to the database that holds transaction log tables as the TLOG database.

Setup SimpleJTA UserTransaction object

Creating the SimpleJTA UserTransaction implementation also creates an instance of the SimpleJTA Transaction Manager. Each instance of SimpleJTA Transaction Manager must be provided a unique id. This id can be any sequence of characters - with a maximum length of 32 characters.

An instance of SimpleJTA TM is specific to a classloader within the JVM. In some environments, such as J2EE Servlets, each Servlet context can have its own instance of the transaction manager. Multiple instances of the transaction manager can share the same log tables. The unique id allocated to each instance enables the transaction manager to know which transactions are related to it.

To create the SimpleJTA UserTransaction implementation, simply create a new SimpleUserTransaction object supplying it a set of properties. This is designed to be called from a factory implementation. The following properies need to be supplied:

TMGR.id
This must be set to the unique id for the transaction manager instance.
TMGR.recoveryUser
Optional - if supplied, this userid must exist in all databases that will participate in a global transaction. SimpleTransactionManager will use this id for resolving in-doubt transactions during restart recovery. Note that many databases require special privileges to be granted to the recoveryUser id. For details please see the Vendor Specific page .
TMGR.recoveryPassword
Required if TMGR.recoveryUser is defined. This should be set to the password for the recoveryUser id.
TLOG.driver
The typeid of the driver that should be used for accessing the TLOG database. At present, this can be of of two values - DERBY.EMBEDDED or ORACLE
TLOG.url
The url for connecting to the TLOG database.
TLOG.user
The user to be used for authenticating to the JDBC driver.
TLOG.password
Password for above user.

Example:

    Properties props = new Properties();
    props.setProperty("TMGR.id", "TMGR.1");
    props.setProperty("TMGR.recoveryUser", "recouser");
    props.setProperty("TMGR.recoveryPassword", "recouser");
    props.setProperty("TLOG.driver", "ORACLE");
    props.setProperty("TLOG.url", "jdbc:oracle:thin:@localhost:1521:db");
    props.setProperty("TLOG.user", "tlog");
    props.setProperty("TLOG.password", "tlog");
    UserTransaction ut = new SimpleUserTransaction(props);

Typically, you will set this up in some kind of configuration file.

Restart Recovery issues

There are two ways in which SimpleJTA resource recovery can be configured.

Setup Datasources

There are currently two Datasource implementations in SimpleJTA - Oracle and Derby. The Oracle datasource implementation is org.simplejta.tm.datasource.SimpleOracleXADataSource , and the Derby implementation is org.simplejta.tm.datasource.SimpleDerbyXADataSource .Note that the Derby implementation uses the Embedded Derby driver.

Both of these implementations take the following parameters:

String tmid
This must be set to the unique id for the transaction manager instance.
String url
The url for connecting to the application database.
String user
The user to be used for authenticating to the JDBC driver.
String password
Password for above user.

Example:

    DataSource ds1 = new SimpleOracleXADataSource("TMGR.1", 
                        "jdbc:oracle:thin:@localhost:1521:db", 
                        "appuser", 
                        "password");

Write your code

Once you have created the SimpleUserTransaction object and the Datasources, you are ready to write code, much in the same way as you would with any UserTransaction implementation.

Example:

    System.err.println("starting new transaction");
    ut.begin();

    /* get connections */
    Connection conn1 = ds1.getConnection();
    Connection conn2 = ds2.getConnection();

    /* do work */
    System.err.println("inserting data");
    Statement stmt1 = conn1.createStatement();
    stmt1.executeUpdate("INSERT INTO job_definition 
                (jobid, jobname, priority, max_concurrency, start_constraint, classname, userdata) 
                 VALUES (jobid_seq.nextval, 'TestJob1', 1, 1, 1, 'org.dm.test.TestBatch', null)");
    stmt1.close();

    Statement stmt2 = conn2.createStatement();
    stmt2.executeUpdate("INSERT INTO dept VALUES (50, 'BSD', 'LONDON')");
    stmt2.close();

    conn1.close();
    conn2.close();

    /* commit */
    System.err.println("commiting inserts");
    ut.commit();

General Usage Notes

Integrating with Spring Framework

SimpleJTA can be integrated easily with Spring Framework . The steps to follow are described below:

Define a bean for SimpleTransactionManager

<bean id="TransactionManager" 
      class="org.simplejta.tm.SimpleTransactionManager" 
      factory-method="getTransactionManager"
      destroy-method="shutdown">
 <constructor-arg>
  <props>
   <prop key="TMGR.id">TM1</prop>
   <prop key="TLOG.driver">DERBY.EMBEDDED</prop>
   <prop key="TLOG.url">/derby/databases/tca</prop>
   <prop key="TLOG.user">APP</prop>
   <prop key="TLOG.password">APP</prop>
  </props>
 </constructor-arg>
</bean> 

Notice that the shutdown method is defined as the destroy-method.

Define a bean for SimpleUserTransaction

<bean id="UserTransaction" 
      class="org.simplejta.tm.ut.SimpleUserTransaction" 
      depends-on="TransactionManager">
 <property name="properties">
  <props>
   <prop key="TMGR.id">TM1</prop>
   <prop key="TLOG.driver">DERBY.EMBEDDED</prop>
   <prop key="TLOG.url">/derby/databases/tca</prop>
   <prop key="TLOG.user">APP</prop>
   <prop key="TLOG.password">APP</prop>
  </props>
 </property>
</bean> 

Notice that the UserTransaction bean is defined as a dependent of the TransactionManager bean. This ensures correct sequence of construction.

Link the UserTransaction and TransactionManager beans to JtaTransactionManager

<bean id="SpringTransactionManager" 
      class="org.springframework.transaction.jta.JtaTransactionManager">
 <property name="userTransaction"><ref local="UserTransaction"/></property>
 <property name="transactionManager"><ref local="TransactionManager"/></property>
</bean>

Create SimpleJTA managed DataSources

<bean id="DataSource" 
      class="org.simplejta.tm.datasource.SimpleOracleXADataSource" 
      depends-on="UserTransaction">
 <property name="tmid"><value>TM1</value></property>
 <property name="url"><value>jdbc:oracle:thin:@localhost:1521:db92010</value></property>
 <property name="user"><value>scott</value></property>
 <property name="password"><value>tiger</value></property>
</bean>

Notice that the DataSource bean is defined as a dependent of the UserTransaction bean. This ensures correct sequence of construction.

Integrating with Tomcat JNDI Context

Following shows how to integrate SimpleJTA with Tomcat's JNDI implementation. Note that this description applies to Tomcat 5.5.9 and above.

Libraries

Include SimpleJTA and other libraries in you web applications WEB-INF/lib folder. Typically, you will require the jar files for SimpleJTA, Log4J, JMS and JTA. You will also need vendor specific jar files for appropriate JDBC or JMS clients.

Declare resource requirements

In your web applications web.xml file, declare the resources your application will use. You must declare the UserTransaction resource and one or more Datasource resources. And example is given below:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
    ...
    <resource-env-ref>
        <resource-env-ref-name>jta/UserTransaction</resource-env-ref-name>
        <resource-env-ref-type>javax.transaction.UserTransaction</resource-env-ref-type>
    </resource-env-ref>
    <resource-env-ref>
        <resource-env-ref-name>jdbc/Datasource</resource-env-ref-name>
        <resource-env-ref-type>javax.sql.DataSource</resource-env-ref-type>
    </resource-env-ref>
    </web-app>
  

Configure Tomcat's Resource Factory

Create context.xml file in your application's META-INF folder, and configure your resources as shown in the example below:

<?xml version="1.0" encoding="UTF-8"?>
<Context path="/SimpleJTASample">
    <Resource name="jta/UserTransaction" auth="Container"
            type="javax.transaction.UserTransaction"
            factory="org.simplejta.tm.ut.SimpleUserTransactionFactory"
            tmgrId="TM1" tmgrRecoveryUser="recouser" tmgrRecoveryPassword="recouser"
            tlogDriver="DERBY.EMBEDDED" tlogUrl="/derby/databases/tca" 
            tlogUser="APP" tlogPassword="APP"
            />
    <Resource name="jdbc/Datasource" auth="Container"
            type="javax.sql.DataSource"
            factory="org.simplejta.tm.datasource.SimpleXADataSourceFactory"
            className="org.simplejta.tm.datasource.SimpleDerbyXADataSource"
            tmid="TM1" url="/derby/databases/tca" user="APP" password="APP"
            />
</Context>      
  

Note the SimpleJTA provides custom implementations of ObjectFactory that can be used as Tomcat Resource Factories.

UserTransaction ObjectFactory
Tomcat Resource attribute Description
type javax.transaction.UserTransaction
factory org.simplejta.tm.ut.SimpleUserTransactionFactory
tmrId Same as SimpleJTA property TMGR.ID
tmgrRecoveryUser Same as SimpleJTA property TMGR.recoveryUser
tmgrRecoveryPassword Same as SimpleJTA property TMGR.recoveryPassword
tlogDriver Same as SimpleJTA property TLOG.driver
tlogUrl Same as SimpleJTA property TLOG.url
tlogUser Same as SimpleJTA property TLOG.user
tlogPassword Same as SimpleJTA property TLOG.password

Following table describes the attributes for Datasource Resource factories:

Datasource ObjectFactory
Tomcat Resource attribute Description
type javax.sql.DataSource
factory org.simplejta.tm.datasource.SimpleXADataSourceFactory
className SimpleJTA DataSource implementation class.
tmid Same as SimpleJTA tmid property for DataSources.
url Same as SimpleJTA url property for DataSources.
user Same as SimpleJTA user property for DataSources.
password Same as SimpleJTA password property for DataSources.

Use resources in your application

Example code is shown below:

        Context initCtx = new InitialContext();
        Context envCtx = (Context) initCtx.lookup("java:comp/env");
        UserTransaction ut = (UserTransaction) envCtx.lookup("jta/UserTransaction");
        DataSource ds = (DataSource) envCtx.lookup("jdbc/Datasource");
          
        ut.begin();
        try {
            Connection conn = ds.getConnection();
            try {
                // do some work here
            }
            finally {
                if (conn != null) {
                     conn.close();
                }
            }
        }
        finally {
            ut.commit();
        }
  

SourceForge.net Logo