Transactions with JTA

This example illustrates how to manage a distributed transaction with multiple XA capable databases. The source files are:
Test.java               // Test program using two XAResources.

1 Compiling and Executing

Use the supplied ANT script to compile and execute the example programs. To compile run:
ant
To execute the tests run:
ant run

2 Test Implementation

This program illustrates how to initialize the transaction manager, and manage a distributed transaction with multiple XA capable databases.
package txjta;
                                                                           
import java.util.Properties;
                                                                           
import java.sql.*;
import javax.sql.*;
                                                                           
import javax.transaction.xa.XAResource;
import javax.transaction.TransactionManager;
                                                                           
import org.omg.CORBA.ORB;
                                                                           
import com.sssw.jts.api.TransactionService;
import com.sssw.jbroker.api.transaction.TSIdentification;
                                                                           
import common.ResourceMapper;
import common.TestDataSource;
                                                                           
public class Test
{
    private static TestDataSource  _db1;
    private static TestDataSource  _db2;
                                                                           
    public static void main(String args[]) throws Exception
    {
    |   // Create a ResourceHandleMapper
    |   ResourceMapper resMapper = new ResourceMapper();
    |                                                                      
    |   System.setProperty("transaction.service.id", "EXAMPLE-TXJTA");
    |                                                                      
    |   // Initialize the ORB and get instance of TM
    |   ORB orb = ORB.init(args, null);
    |   TransactionService ts = (TransactionService)
    |       orb.resolve_initial_references("TransactionService");
    |                                                                      
    |   //
    |   // Recover TM with COLD Start.
    |   //
    |   ts.recover(resMapper, true, null);
    |                                                                      
    |   TransactionManager tm = ts.getTransactionManager();
    |                                                                      
    |   //
    |   _db1 = new TestDataSource(TestDataSource._testDB1);
    |   _db2 = new TestDataSource(TestDataSource._testDB2);
    |                                                                      
    |   // create test tables
    |   createTables();
    |                                                                      
    |   // Establish connections to databases
    |   //
    |   XAConnection        xaco1 = _db1.getXAConnection();
    |   XAResource          xars1 = xaco1.getXAResource();
    |   Connection          conn1 = xaco1.getConnection();
    |   resMapper.addResource(xars1);
    |                                                                      
    |   XAConnection        xaco2 = _db2.getXAConnection();
    |   XAResource          xars2 = xaco2.getXAResource();
    |   Connection          conn2 = xaco2.getConnection();
    |   resMapper.addResource(xars2);
    |                                                                      
    |   // Start a transaction
    |   System.out.println("Begin First Transaction");
    |   tm.begin();
    |   tm.getTransaction().enlistResource(xars1);
    |   tm.getTransaction().enlistResource(xars2);
    |                                                                      
    |   System.out.println("Insert values(11, 12) into "+_db1+" - "+TestDataSource._testTB1);
    |   insertValue(conn1, TestDataSource._testTB1, "11", "12");
    |                                                                      
    |   System.out.println("Insert values(11, 12) into "+_db2+" - "+TestDataSource._testTB2);
    |   insertValue(conn2, TestDataSource._testTB2, "11", "12");
    |                                                                      
    |   tm.getTransaction().delistResource(xars1, XAResource.TMSUCCESS);
    |   tm.getTransaction().delistResource(xars2, XAResource.TMSUCCESS);
    |                                                                      
    |   tm.rollback();
    |   System.out.println("Rollback First Transaction");
    |   // Ended the Transaction with ROLLBACK
    |                                                                      
    |   // Make sure rollback removed the rows
    |   checkNotExists(_db1, TestDataSource._testTB1, "11", "12");
    |   checkNotExists(_db2, TestDataSource._testTB2, "11", "12");
    |                                                                      
    |   // Start a second transaction
    |   System.out.println("Begin Second Transaction");
    |   tm.begin();
    |   tm.getTransaction().enlistResource(xars2);
    |   tm.getTransaction().enlistResource(xars1);
    |                                                                      
    |   System.out.println("Insert values(21, 22) into "+_db1+" - "+TestDataSource._testTB1);
    |   insertValue(conn1, TestDataSource._testTB1, "21", "22");
    |                                                                      
    |   System.out.println("Insert values(21, 22) into "+_db2+" - "+TestDataSource._testTB2);
    |   insertValue(conn2, TestDataSource._testTB2, "21", "22");
    |                                                                      
    |   tm.getTransaction().delistResource(xars1, XAResource.TMSUCCESS);
    |   tm.getTransaction().delistResource(xars2, XAResource.TMSUCCESS);
    |   tm.commit();
    |   System.out.println("Commit Second Transaction");
    |   // Ended the Transaction with COMMIT
    |                                                                      
    |   // Make sure commit completed...
    |   checkExists(_db1, TestDataSource._testTB1, "21", "22");
    |   checkExists(_db2, TestDataSource._testTB2, "21", "22");
    |                                                                      
    |   xaco1.close();
    |   xaco2.close();
    |                                                                      
    |   _db1.shutdown();
    |   _db2.shutdown();
    }
                                                                           
    //
    // DATABASE Connection Initialization
    //
    static Connection getSQLConnection(String dbname) throws Exception
    {
    |   Class.forName("COM.cloudscape.core.JDBCDriver").newInstance();
    |   return DriverManager.getConnection("jdbc:cloudscape:../../"+dbname+";create=true");
    }
                                                                           
    //
    // Create test tables
    //
    static void createTables() throws Exception
    {
    |   Connection conn;
    |   conn = _db1.getConnection();
    |   createTable(conn, TestDataSource._testTB1);
    |   conn.close();
    |                                                                      
    |   conn = _db2.getConnection();
    |   createTable(conn, TestDataSource._testTB2);
    |   conn.close();
    }
                                                                           
    //
    // Create test table
    //
    static void createTable(Connection conn, String tablename) throws Exception
    {
    |   Statement stmt = null;
    |   try 
    |   {
    |   |   stmt = conn.createStatement();
    |   |   try
    |   |   {
    |   |   |   int nrow = stmt.executeUpdate("DELETE FROM "+tablename);
    |   |   |   System.out.println("Deleted "+nrow+" rows from table "+tablename);
    |   |   }
    |   |   catch (SQLException ex)
    |   |   {
    |   |   |   stmt.execute("CREATE TABLE "+tablename+"(COL1 INTEGER, COL2 INTEGER)");
    |   |   |   System.out.println("Created table "+tablename);
    |   |   }
    |   }
    |   finally
    |   {
    |   |   if (stmt != null) { try { stmt.close(); } catch (Exception ex) {} }
    |   }
    }
                                                                           
    static void insertValue(Connection conn, String tab, String v1, String v2)
    throws Exception
    {
    |   Statement stmt = conn.createStatement();
    |   stmt.execute("INSERT INTO "+tab+" (COL1, COL2) VALUES ("+v1+", "+v2+")");
    |   stmt.close();
    }
                                                                           
    static void checkNotExists(TestDataSource db, String tab, String v1, String v2)
    throws Exception
    {
    |   Connection  conn;
    |   Statement   stmt;
    |   ResultSet   rset;
    |   conn = db.getConnection();
    |   stmt = conn.createStatement();
    |   rset = stmt.executeQuery("SELECT COL2 FROM "+tab+" WHERE COL1="+v1);
    |   if (rset.next())
    |   {
    |   |   System.out.println("FAILED: Value("+v1+","+rset.getInt(1)+") in "+db+"-"+tab);
    |   }
    |   else
    |   {
    |   |   System.out.println("Value("+v1+","+v2+") not in table "+db+"-"+tab+" ... Ok");
    |   }
    |   rset.close();
    |   stmt.close();
    |   conn.close();
    }
    static void checkExists(TestDataSource db, String tab, String v1, String v2)
    throws Exception
    {
    |   Connection  conn;
    |   Statement   stmt;
    |   ResultSet   rset;
    |   conn = db.getConnection();
    |   stmt = conn.createStatement();
    |   rset = stmt.executeQuery("SELECT COL2 FROM "+tab+" WHERE COL1="+v1);
    |   if (!rset.next())
    |   {
    |   |   System.out.println("FAILED: Value("+v1+","+v2+") not in "+db+"-"+tab);
    |   }
    |   else
    |   {
    |   |   System.out.println("Values("+v1+","+rset.getInt(1)+") in table "+db+"-"+tab+" ... Ok");
    |   }
    |   rset.close();
    |   stmt.close();
    |   conn.close();
    }
}
Copyright © 2000-2003, Novell, Inc. All rights reserved.