This example illustrates how a transaction object participates in a transaction. The transaction object implementation uses XA enable database connection as its storage, and uses the JTA interfaces to perform its work transactionally.
ServerA.java // Server that hosts a Transactional object test.idl // IDL describing the TestXA interface. TestImpl.java // Simple Transactional object implementation.
Use the supplied ANT script to compile and execute the example programs. To compile run:
ant
To execute the test programs run:
ant test
To execute the test programs as a server run:
ant server
This is a simple server program that activates the TestXA
transactional object.
In test mode it uses the object in several transactions which complete with rollback
and commit. In server mode the object is activated and the server waits invocations
from clients.
package transobjxa; import java.io.*; import java.sql.*; import java.util.*; import javax.sql.*; import javax.transaction.TransactionManager; import javax.transaction.xa.XAResource; import org.omg.CORBA.Any; import org.omg.CORBA.ORB; import org.omg.CORBA.Policy; import org.omg.CORBA.Object; import org.omg.PortableServer.POA; import org.omg.PortableServer.Servant; import org.omg.PortableServer.ImplicitActivationPolicyValue; import org.omg.CosTransactions.ADAPTS; import org.omg.CosTransactions.SHARED; import org.omg.CosTransactions.OTS_POLICY_TYPE; import org.omg.CosTransactions.INVOCATION_POLICY_TYPE; import org.omg.CosTransactions.Resource; import org.omg.CosTransactions.TransactionFactory; import com.sssw.jbroker.api.transaction.TSIdentification; import com.sssw.jts.api.TransactionService; import common.Utils; import common.ResourceMapper; import common.TestDataSource; public class ServerA { public static void main(String args[]) throws Exception { | // Create a ResourceHandleMapper | ResourceMapper resMapper = new ResourceMapper(); | | System.setProperty("transaction.service.id", "EXAMPLE-TRANSOBJ-XA"); | | // Initialize the ORB and get instance of TM | if (args.length > 0) | System.setProperty("ORBPort", "44444"); | ORB orb = ORB.init(args, null); | TransactionService ts = (TransactionService) | orb.resolve_initial_references("TransactionService"); | | // | // Recover TM with COLD Start. | // | ts.recover(resMapper, true, null); | | // get the root POA | POA rootPOA = (POA) orb.resolve_initial_references("RootPOA"); | | Servant servant = new TestXAImpl(ts, resMapper, | TestDataSource._testDB1, TestDataSource._testTB1, rootPOA); | | // create a transactional POA | Any otsPolicy = orb.create_any(); | otsPolicy.insert_short(ADAPTS.value); | Any invPolicy = orb.create_any(); | invPolicy.insert_short(SHARED.value); | | POA txPOA = rootPOA.create_POA("txPOA", | rootPOA.the_POAManager(), | new Policy[] { | | rootPOA.create_implicit_activation_policy( | | ImplicitActivationPolicyValue.IMPLICIT_ACTIVATION), | | orb.create_policy(OTS_POLICY_TYPE.value, otsPolicy), | | orb.create_policy(INVOCATION_POLICY_TYPE.value, invPolicy) | }); | | // create a stringified object reference | Object obj = txPOA.servant_to_reference(servant); | String testIOR = orb.object_to_string(obj); | | if (args.length > 0) { | | // write the stringified object reference | | Utils.writeIOR(testIOR, "ior"); | | System.out.println("+ Waiting for invocations ..."); | | orb.run(); | | | } else { | | | | // activate the Root POA | | txPOA.the_POAManager().activate(); | | rootPOA.the_POAManager().activate(); | | | | TestXA test = TestXAHelper.narrow(obj); | | | | for (int i=1; i<=5; i++) { | | | System.out.println(); | | | System.out.println("+ Start Transaction "+i); | | | ts.getTransactionCurrent().begin(); | | | test.insert(i, 10+i); | | | System.out.println("+ In Transaction Find("+i+") => "+(10+i)+" => "+test.findv2(i)); | | | | | | if ((i % 2) == 1) { | | | | ts.getTransactionCurrent().rollback(); | | | | System.out.println("+ After Rollback Find("+i+") => -1 => "+test.findv2(i)); | | | } else { | | | | ts.getTransactionCurrent().commit(false); | | | | System.out.println("+ After Commit Find("+i+") => "+(10+i)+" => "+test.findv2(i)); | | | } | | } | } } }
The IDL describing the TestXA
interface.
#include "CosTransactions.idl" module transobjxa { exception DidNotWork {}; interface TestXA { | void insert(in unsigned long v1, in unsigned long v2) raises(DidNotWork); | unsigned long findv2(in unsigned long v1) raises(DidNotWork); | unsigned long remove(in unsigned long v1) raises(DidNotWork); }; };
This is an implementation of an transactional object that uses XA and JTA interfaces to perform transactional operations. Using a database as its storage.
package transobjxa; import java.sql.*; import java.util.*; import javax.sql.*; import javax.transaction.Transaction; import javax.transaction.TransactionManager; import javax.transaction.xa.XAResource; import org.omg.CORBA.ORB; import org.omg.PortableServer.POA; import org.omg.CosTransactions.Current; import com.sssw.jts.api.TransactionService; import common.ResourceMapper; import common.TestDataSource; public class TestXAImpl extends TestXAPOA { TransactionManager _tm; Current _current; ResourceMapper _resMapper; String _dbase; String _table; TestDataSource _xads; XAConnection _xaconn; static int _counter = 1; TestXAImpl(TransactionService ts, ResourceMapper rm, String dbase, String table, POA rootPOA) throws Exception { | _tm = ts.getTransactionManager(); | _current = ts.getTransactionCurrent(); | _resMapper = rm; | _dbase = dbase; | _table = table; | _xads = null; | _xaconn = null; } private void init() throws Exception { | if (_xads == null) { | | _xads = new TestDataSource(_dbase); | | createTable(); | } | | if (_xaconn == null) | _xaconn = _xads.getXAConnection(); } public void term() { | try {_xaconn.close(); }catch(Exception e) {} } public void insert(int v1, int v2) throws DidNotWork { | try | { | | init(); | | XAResource xares = _xaconn.getXAResource(); | | Connection conn = _xaconn.getConnection(); | | _resMapper.addResource(xares); | | | | _tm.getTransaction().enlistResource(xares); | | | | System.out.println("+ Insert values("+v1+", "+v2+") into "+_dbase+" - "+_table); | | Statement stmt = conn.createStatement(); | | stmt.execute("INSERT INTO "+_table+" (COL1, COL2) VALUES ("+v1+", "+v2+")"); | | stmt.close(); | | | | _tm.getTransaction().delistResource(xares, XAResource.TMSUSPEND); | | | | conn.close(); | } | catch (Exception ex) | { | | ex.printStackTrace(); | | throw new DidNotWork(); | } } public int findv2(int v1) throws DidNotWork { | try | { | | init(); | | int rval = -1; | | Transaction trans = _tm.getTransaction(); | | XAResource xares = null; | | Connection conn; | | | | if (trans != null) { | | | xares = _xaconn.getXAResource(); | | | conn = _xaconn.getConnection(); | | | trans.enlistResource(xares); | | } else { | | | xares = null; | | | conn = _xads.getConnection(); | | } | | | | Statement stmt = conn.createStatement(); | | ResultSet rset = stmt.executeQuery("SELECT COL2 FROM "+_table+" WHERE COL1="+v1); | | | | if (rset.next()) | | { | | | rval = rset.getInt(1); | | } | | rset.close(); | | stmt.close(); | | conn.close(); | | | | if (trans != null) { | | | trans.delistResource(xares, XAResource.TMSUSPEND); | | } | | | | return rval; | } | catch (Exception ex) | { | | ex.printStackTrace(); | | throw new DidNotWork(); | } } public int remove(int v1) throws DidNotWork { | int nrows = 0; | try | { | | init(); | | int rval = -1; | | Connection conn = _xads.getConnection(); | | Statement stmt = conn.createStatement(); | | nrows = stmt.executeUpdate("DELETE FROM "+_table+" WHERE COL1="+v1); | | | | stmt.close(); | | conn.close(); | } | catch (Exception ex) | { | | ex.printStackTrace(); | | throw new DidNotWork(); | } | return nrows; } // // Create test table // void createTable() throws Exception { | Connection conn = null; | Statement stmt = null; | try | { | | conn = _xads.getConnection(); | | stmt = conn.createStatement(); | | try | | { | | | int nrow = stmt.executeUpdate("DELETE FROM "+_table); | | | System.out.println("+ Deleted "+nrow+" rows from table "+_dbase+"."+_table); | | } | | catch (SQLException ex) | | { | | | System.out.println("+ Creating table "+_dbase+"."+_table+" ... "); | | | stmt.execute("CREATE TABLE "+_table+"(COL1 INTEGER, COL2 INTEGER)"); | | } | } | finally | { | | if (stmt != null) { try { stmt.close(); } catch (Exception ex) {} } | | if (conn != null) { try { conn.close(); } catch (Exception ex) {} } | } } }
Copyright © 2003, 2004 Novell, Inc. All rights reserved. Copyright © 2001, 2002, 2003 SilverStream Software, LLC. All rights reserved.