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:
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.
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:
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.
There are two ways in which SimpleJTA resource recovery can be configured.
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:
Example:
DataSource ds1 = new SimpleOracleXADataSource("TMGR.1", "jdbc:oracle:thin:@localhost:1521:db", "appuser", "password");
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();
SimpleJTA can be integrated easily with Spring Framework . The steps to follow are described below:
<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
.
<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.
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>
<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.
Following shows how to integrate SimpleJTA with Tomcat's JNDI implementation. Note that this description applies to Tomcat 5.5.9 and above.
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.
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>
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.
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:
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. |
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(); }