This example illustrates how a transaction object participates in a transaction.
The transaction object implementation uses a simple resource as its
storage. The SimpleResource
object implements the resource methods to make it
compliant with transaction services.
ServerA.java // Server that hosts a Transactional object test.idl // IDL describing the SimpleResource and TestRes interfaces. SimpleResourceImpl.java // Simple CORBA Resource implementation. TestXAImpl.java // Transactional object implementation using XA.
Use the supplied ANT build 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 TestRes
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 transobjres; import java.io.*; import java.sql.*; import java.util.*; import javax.sql.*; import javax.transaction.xa.XAResource; import javax.transaction.TransactionManager; 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.jts.api.TransactionService; import com.sssw.jbroker.api.transaction.TSIdentification; 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-RES"); | | // Initialize the ORB and get instance of TM | if (args.length > 0) | System.setProperty("ORBPort", "55555"); | 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 TestResImpl(ts, 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(); | | | | TestRes test = TestResHelper.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 SimpleResource
and TestRes
interfaces.
#include "CosTransactions.idl" module transobjres { exception DidNotWork {}; interface TestRes { | 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); }; interface SimpleResource : CosTransactions::Resource { | 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 a very simplistic implementation of the Resource
interface.
Its purpose is to illustrate how such objects can be used in distributed transactions.
package transobjres; import java.sql.*; import java.util.*; import org.omg.CosTransactions.Vote; import org.omg.CosTransactions.Current; import org.omg.CosTransactions.Resource; import org.omg.CosTransactions.NotPrepared; import org.omg.CosTransactions.HeuristicMixed; import org.omg.CosTransactions.HeuristicCommit; import org.omg.CosTransactions.HeuristicHazard; import org.omg.CosTransactions.HeuristicRollback; import common.Utils; import common.TestDataSource; /* * This is very simple implementation of CORBA Resource. * It only keeps values in memory and does not do any * real storage. */ public class SimpleResourceImpl extends SimpleResourcePOA { private String _name; private Hashtable _perm; private Hashtable _temp; private boolean _prepared; SimpleResourceImpl(String name) throws Exception { | _name = name; | _prepared = false; | _perm = new Hashtable(); | _temp = new Hashtable(); } public void insert(int key, int val) { | _temp.put(new Integer(key), new Integer(val)); } public int findv2(int key) { | Integer val = (Integer)_temp.get(new Integer(key)); | | if (val == null) | val = (Integer)_perm.get(new Integer(key)); | | if (val == null) | return -1; | | return val.intValue(); } public int remove(int keyval) { | Integer key = new Integer(keyval); | Integer val = (Integer)_temp.get(key); | | if (val != null) { | | _temp.remove(key); | | return 1; | } | return 0; } public Vote prepare() throws HeuristicMixed, HeuristicHazard { | if (_prepared) | throw new HeuristicHazard(); | | for (Enumeration e = _temp.keys(); e.hasMoreElements() ;) { | | Object key = e.nextElement(); | | _perm.put(key, _temp.get(key)); | } | _prepared = true; | System.out.println("+ SimpleResource "+_name+" prepare() -> VoteCommit"); | return Vote.VoteCommit; } public void rollback() throws HeuristicCommit, HeuristicMixed, HeuristicHazard { | if (_prepared) { | | for (Enumeration e = _temp.keys(); e.hasMoreElements() ;) { | | | Object key = e.nextElement(); | | | _perm.remove(key); | | } | } | _temp = new Hashtable(); | _prepared = false; | System.out.println("+ SimpleResource "+_name+" rollback()"); } public void commit() throws NotPrepared, HeuristicRollback, HeuristicMixed, HeuristicHazard { | if (!_prepared) | throw new NotPrepared(); | | _temp = new Hashtable(); | _prepared = false; | System.out.println("+ SimpleResource "+_name+" commit()"); } public void commit_one_phase() throws HeuristicHazard { | for (Enumeration e = _temp.keys(); e.hasMoreElements() ;) { | | Object key = e.nextElement(); | | _perm.put(key, _temp.get(key)); | } | _temp = new Hashtable(); | _prepared = false; | System.out.println("+ SimpleResource "+_name+" commit-one-phase()"); } public void forget() { } }
This is an implementation of an transactional object that uses the
SimpleResource
implementation as its storage.
package transobjres; import java.sql.*; import javax.sql.*; import java.util.*; import javax.transaction.Transaction; import javax.transaction.TransactionManager; import javax.transaction.xa.XAResource; import com.sssw.jts.api.TransactionService; import org.omg.CORBA.ORB; import org.omg.PortableServer.POA; import org.omg.CosTransactions.Current; public class TestResImpl extends TestResPOA { Current _current; SimpleResource _simp_res; Hashtable _regtrans; static int _counter = 1; TestResImpl(TransactionService ts, POA rootPOA) throws Exception { | _current = ts.getTransactionCurrent(); | _simp_res = (SimpleResource)rootPOA.servant_to_reference( | new SimpleResourceImpl("Simple-"+_counter++)); | _regtrans = new Hashtable(); } private void init() throws Exception { } public void term() { } public void insert(int v1, int v2) throws DidNotWork { | try | { | | init(); | | String tran = _current.get_transaction_name(); | | if (_regtrans.get(tran) == null) { | | | _current.get_control().get_coordinator().register_resource(_simp_res); | | | _regtrans.put(tran, tran); | | } | | System.out.println("+ Insert values("+v1+", "+v2+") into SimpleResource"); | | _simp_res.insert(v1, v2); | } | catch (Exception ex) | { | | ex.printStackTrace(); | | throw new DidNotWork(); | } } public int findv2(int v1) throws DidNotWork { | try | { | | init(); | | return _simp_res.findv2(v1); | } | catch (Exception ex) | { | | ex.printStackTrace(); | | throw new DidNotWork(); | } } public int remove(int v1) throws DidNotWork { | try | { | | init(); | | return _simp_res.remove(v1); | } | catch (Exception ex) | { | | ex.printStackTrace(); | | throw new DidNotWork(); | } } }
Copyright © 2003, 2004 Novell, Inc. All rights reserved. Copyright © 2001, 2002, 2003 SilverStream Software, LLC. All rights reserved.