Tuesday, December 01, 2009

JTA Transactions with Atomkios in Tomcat

Tomcat is the leading Java Servlet container. Many of our applications do not need full blown Java EE Application Server and a Servlet container like Tomcat is more than enough to run them even in production. Some of our applications need JTA transactions capabilities, which are not provided by Tomcat out of the box. There are very few open source JTA implementations. JOTM used to be most popular among them, unfortunately its development is dead for last several years though it seems to getting revived lately at its new home. Atomikos is another JTA implementation, which was open sourced (Transactions Essentials) when JOTM went into hibernation.

Integrating Atomikos with Tomcat is fairly easy, it can be done by following simple steps given below-

Create a configuration file for Atomikos at $TOMCAT_HOME/lib/transactions.properties location with contents like below-

com.atomikos.icatch.service=com.atomikos.icatch.standalone.UserTransactionServiceFactory
com.atomikos.icatch.automatic_resource_registration=true
com.atomikos.icatch.output_dir=../work
com.atomikos.icatch.log_base_dir=../work
com.atomikos.icatch.enable_logging=true
com.atomikos.icatch.console_log_level=INFO

Define a DataSource in $TOMCAT_HOME/conf/context.xml as shown below-

<Transaction factory="com.atomikos.icatch.jta.UserTransactionFactory" />

<Resource name="jdbc/pgDS"
                auth="Container"
                type="com.atomikos.jdbc.AtomikosDataSourceBean"
                factory="com.vinodsingh.atomikos.tomcat.DataSourceBeanFactory"
                uniqueResourceName="jdbc/pgDS"
                xaDataSourceClassName="org.postgresql.xa.PGXADataSource"
                xaProperties.serverName="localhost"
                xaProperties.portNumber="5432"
                xaProperties.databaseName="test"
                xaProperties.user="test"
                xaProperties.password="test"
                maxPoolSize="3"
                minPoolSize="1" />

Copy following files to $TOMCAT_HOME/lib directory-
  • JDBC driver of the Database being used.
  • JTA API (jta-1.1.jar).
  • Atomikos Essentials (transactions-essentials-all-3.5.9.jar), name may change according to the version being used.
  • Tomcat integration jars available at Atomikos' site or atomikos-tomcat.jar built from the source code attached with this post.
All these changes will make UserTransaction object available in Tomcat's JNDI tree and it can be used in same way as we do in any regular Java EE application server. An example of using UserTransaction is shown in following code snippet-
public String insertRecord(String value) {
    UserTransaction utx = null;
    try {
        utx = ServiceLocator.getTrasactionManager();
        utx.begin();
        // Do transactional work
        pgDAO.insertRecord(value);

        // commit the transaction
        utx.commit();
    } catch (Exception e) {
        try {
            if (utx != null)
                utx.rollback();

            String msg = "Oops! Transaction is rolled back due to an exception";
            log.error(msg, e);
            return msg;
        } catch (Exception e1) {
            log.error("Failed to rollback the transaction", e1);
            return "Failed to rollback the transaction" + e1.getMessage();
        }
    }
    return "Transaction succeded";
}
To see transactions in action compile the attached source code, deploy the generated jta.war on Tomcat and open http://localhost:8080/jta/ URL in your browser. Thats all it takes to integrate Atomikos JTA transactions in Tomcat.

Note:-
  1. Though Atomikos' documentation about Tomcat 6 integration talks about configuring AtomikosLifecycleListener in $TOMCAT_HOME/conf/server.xml as well. But Atomikos seems to work well inside Tomcat without that configuration.
  2. Here I have slightly modified the code for Tomcat integration from what is available at Atomikos website, more details about the same will follow in upcoming posts.

Source code for this post is available here.

13 Comments: