www.arjuna.com news company products standards research library forums contact
Trail map 1. Installation Content 2. The Sample Application 3. Deploying and Testing the Sample Application 4. Making the Sample Application Persistent 5. Recovery From Failure 6. Where Next? Navigation Home Previous Additional Trails Distributed Transaction Processing The X/Open DTP Model The OMG OTS Model Transactions in J2EE Configuring ATS Configuring the Recovery Manager ORB Portability Transactional Object For Java
| print this page
| email this page
> Running and Testing examples #### How the Banking Application is build using JTS interfaces From an architectural point of view of JTS, the bank client is considered as an application program able to manage transactions either in a direct or indirect management mode, respectively with the interfaces org.omg.CosTransactions.TransactionFactory and org.omg.CosTransactions.Terminator or with the org.omg.CosTransactions.Current interface. Transactions created by the client in the Banking application are done in the indirect mode. The following portion of code illustrates how a JTS transaction is started and terminated when the client asks to transfer money from one account to another. This also describes what are ArjunaTS packages that need to be used in order to obtain appropriate objects instances (such Current). Note: The code below is a simplified view of the BankClient.java program. Only the transfer operation is illustrated; other operations manage transactions in the same way. (see for details the BankClient.java)
>     package com.arjuna.demo.jta.localbank;
>     import com.arjuna.ats.jts.OTSManager;
>     import com.arjuna.ats.internal.jts.ORBManager;
>     public class BankClient
>     {
>        private Bank _bank; //Initialised on BankClient initializations
>        ....
>        // This operation is used to make a transfer from an account to another account
>        private void makeTransfer()
>        {
>          System.out.print("Take money from : ");
>          String name_supplier = input();

>          System.out.print("Put money to : ");
>          String name_consumer = input();

>          System.out.print("Transfert amount : ");
>          String amount = input();

>          float famount = 0;
>          try
>           {
>             famount = new Float( amount ).floatValue();
>           }
>          catch ( java.lang.Exception ex )
>           {
>             System.out.println("Invalid float number, abort operation...");
>             return;
>           }

>          try
>           {
>            //the following instruction asks a specific ArjunaTS class to obtain a Current instance
>            Current current = OTSManager.get_current();
>            System.out.println("Beginning a User transaction to get balance");
>            current.begin();

>            Account supplier = _bank.get_account( name_supplier );
>            Account consumer = _bank.get_account( name_consumer );
>            supplier.debit( famount );
>            consumer.credit( famount );

>            current.commit( );
>           }
>          catch (Exception e)
>           {
>            System.err.println("ERROR - "+e);
>           }
>        }
> Since JTS is used invocations against an ORB are needed, such ORB and Object Adapter instantiation and initialisation. To ensure a better portability, the ORB Portability API provides a set of methods that can be used as described below.
>     public static void main( String [] args )
>     {
>       try
>        {
>          myORB = ORB.getInstance("test");// Create an ORB instance
>          myOA = OA.getRootOA(myORB); //Obtain the Root POA
>          myORB.initORB(args, null); //Initialise the ORB
>          myOA.initOA(); //Initialise the POA

>          // The ORBManager is a class provided by ArjunaTS to facilitate the association
>          // of the ORB/POA with the transaction service
>          ORBManager.setORB(myORB);
>          ORBManager.setPOA(myOA);
>          ....
>        }
>        catch(Exception e)
>        {
>          e.printStackTrace(System.err);
>        }
>     }
> The Bank object has mainly two operations: creating an account, which is added in the account list, and returning an Account object. No transactional instruction is performed by the Bank object
>     package com.arjuna.demo.jta.localbank;
>     public class Bank {
>        private java.util.Hashtable _accounts;

>        public Bank()
>        {
>          _accounts = new java.util.Hashtable();
>        }

>        public Account create_account( String name )
>        {
>          Account acc = new Account(name);
>          _accounts.put( name, acc );
>           return acc;
>        }

>        public Account get_account(String name)
>        throws NotExistingAccount
>        {
>          Account acc = ( Account ) _accounts.get( name );
>          if ( acc == null )
>            throw new NotExistingAccount("The Account requested does not exist");
>          return acc;
>        }
>     }
> The Account object provides mainly three methods balance, credit and withdraw. However, in order to provide the transactional behaviour, rather than to modify the current account directly (according to credit or withdraw) this task is delegated to an AccountResource object that is able, according to the transaction outcome, to set the account value either to its initial state or its final state. The AccountResource object is in fact an object that implements the org.omg.CosTransactions.Resource, then able to participate to the transaction commitment. For this aim, the Account object has to register the AccountResource object as a participant, after having obtaining the reference of the org.omg.CosTransactions.Coordinator object , itself obtained via the org.omg.CosTransactions.Control object
>     package com.arjuna.demo.jta.localbank;

>     public class Account
>     {
>        float _balance;
>        AccountResource accRes = null;

>        public Account(String name )
>        {
>          _name = name;
>          _balance = 0;
>        }

>        public float balance()
>        {
>          return getResource().balance();;
>        }

>        public void credit( float value )
>        {
>          getResource().credit( value );
>        }

>        public void debit( float value )
>        {
>          getResource().debit( value );
>        }

>        public AccountResource getResource()
>     	{
>           try
>     	   {

>         if (accRes == null) {
>              accRes = new AccountResource(this, _name) ;
>              Resource ref = org.omg.CosTransactions.ResourceHelper.narrow(ORBManager.getPOA().corbaReference(accRes));
>              // Note above the possibilities provided by the ORBManager to access the POA then to obtain
>              // the CORBA reference of the created AccountResource object

>              RecoveryCoordinator recoverycoordinator = OTSManager.get_current().get_control().
>                                                    get_coordinator().register_resource(ref);

>             }
>           }
>           catch (Exception e)
>           {
>             System.err.println("ERROR - "+e);
>           }

>           return accRes;
>        }
>        ...
>     }
> To be considered as a org.omg.CosTransactions.Resource, the AccountResource class shall extends the class org.omg.CosTransactions.ResourcePOA generated by the CORBA IDL compiler. The AccountRessource provides similar methods as the Account class (credit, withdraw and balance) with the appropriate methods to participate to the 2PC protocol. The following portion of code describes how the methods prepare, commit and rollback are implemented.
>     public class AccountResource extends org.omg.CosTransactions.ResourcePOA
>     {
>        public AccountResource(Account account, String name )
>        {
>          _name = name;
>          _account = account;
>          _initial_balance = account._balance;
>          _current_balance = _initial_balance;
>        }

>        public float balance()
>        {
>          return _current_balance;
>        }

>        public void credit( float value )
>        {
>          _current_balance += value;
>        }

>        public void debit( float value )
>        {
>          _current_balance -= value;
>        }

>        public org.omg.CosTransactions.Vote prepare()
>     	   throws org.omg.CosTransactions.HeuristicMixed, org.omg.CosTransactions.HeuristicHazard
>         {
>     	  if ( _initial_balance == _current_balance )
>            return org.omg.CosTransactions.Vote.VoteReadOnly;
>          if ( _current_balance < 0 )
>            return org.omg.CosTransactions.Vote.VoteRollback;
>          return org.omg.CosTransactions.Vote.VoteCommit;
>         }

>        public void rollback()
>          throws org.omg.CosTransactions.HeuristicCommit, org.omg.CosTransactions.HeuristicMixed,
>                                 org.omg.CosTransactions.HeuristicHazard
>        {
>          //Nothing to do
>        }

>        public void commit()
>          throws org.omg.CosTransactions.NotPrepared, org.omg.CosTransactions.HeuristicRollback,
>                           org.omg.CosTransactions.HeuristicMixed, org.omg.CosTransactions.HeuristicHazard
>        {
>           _account._balance = _current_balance;
>        }

>        public void commit_one_phase()
>          throws org.omg.CosTransactions.HeuristicHazard
>        {
>          _account._balance = _current_balance;
>        }

>        .....
>        private float _initial_balance;
>        private float _current_balance;
>        private Account _account;

>        }
##### Sample Application Source Code Full source code for the banking application is included to provide you with a starting point for experimentation. JTS Version BankClient.java Bank.java Account.java AccountRessource.java NotExistingAccount.java
Copyright 2002-2005 Arjuna Technologies All Rights Reserved. info@arjuna.com +44 191 243 0676