<?xml version="1.0"?>
<!--
  JBoss, Home of Professional Open Source
  Copyright 2006, JBoss Inc., and individual contributors as indicated
  by the @authors tag.  All rights reserved. 
  See the copyright.txt in the distribution for a full listing 
  of individual contributors.
  This copyrighted material is made available to anyone wishing to use,
  modify, copy, or redistribute it subject to the terms and conditions
  of the GNU General Public License, v. 2.0.
  This program is distributed in the hope that it will be useful, but WITHOUT A 
  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 
  PARTICULAR PURPOSE.  See the GNU General Public License for more details.
  You should have received a copy of the GNU General Public License,
  v. 2.0 along with this distribution; if not, write to the Free Software
  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
  MA  02110-1301, USA.
  
  (C) 2005-2006,
  @author JBoss Inc.
-->
<page title="Arjuna Technologies Limited: Trail map: Running and Testing Examples" rootpath="../..">
	<header>         What is Transactional Object For Java  </header>
	<content>
		<navigation>
			<links include="includes/www_arjuna_com_navigation.xml"/>
			<links include="includes/trailmap_navigation.xml"/>
			<links title="Navigation">
				<link ref="index.html">Home</link>
			</links>
			<links include="includes/trailmap_additional.xml"/>
		</navigation>
		<area title="What is Transactional Object For Java">
			<html>
				<p>ArjunaCore exploits object-oriented techniques to present programmers with 
  a toolkit of Java classes from which application classes can inherit to obtain 
  desired properties, such as persistence and concurrency control. These classes 
  form a hierarchy, part of which is shown below.</p>
				<p>
					<img src="includes/ArjunaCore_Classes.GIF"/>
				</p>
				<p>Figure 1 - ArjunaCore class hierarchy.</p>
				<p>Apart from specifying the scopes of transactions, and setting appropriate locks 
  within objects, the application programmer does not have any other responsibilities: 
  ArjunaCore and Transactional Objects for Java (TXOJ) guarantee that transactional 
  objects will be registered with, and be driven by, the appropriate transactions, 
  and crash recovery mechanisms are invoked automatically in the event of failures.</p>
				<h4>Recovery and Persistency</h4>
				<p>Making an object persistent and recoverable means that we shall be able to 
  store its final state or to retrieve its initial state according to the final 
  status of a transaction even in the presence of failures. ArjunaCore provides 
  a set of techniques to save to and to retrieve from the Object Store states 
  of objects. All objects made persistent with these ArjunaCore mechanisms are 
  assigned unique identifiers (instances of the Uid class), when they are created, 
  and this is to identify them within the object store. Due to common functionality 
  for persistency and recovery required by several applications, objects are stored 
  and retrieved from the object store using the same mechanism: the classes OutputObjectState 
  and InputObjecState.</p>
				<p>At the root of the class hierarchy, given in Figure 1, is the class StateManager. 
  This class is responsible for object activation and deactivation and object 
  recovery. The simplified signature of the class is:</p>
				<blockquote>
					<pre>public abstract class StateManager
{
   public boolean activate ();
   public boolean deactivate (boolean commit);
   public Uid get_uid (); // object&#8217;s identifier.

   // methods to be provided by a derived class
   public boolean restore_state (InputObjectState os);
   public boolean save_state (OutputObjectState os);

   protected StateManager ();
   protected StateManager (Uid id);
};</pre>
				</blockquote>
				<p> Objects are assumed to be of three possible flavours. They may simply be recoverable, 
  in which case StateManager will attempt to generate and maintain appropriate 
  recovery information for the object. Such objects have lifetimes that do not 
  exceed the application program that creates them. Objects may be recoverable 
  and persistent, in which case the lifetime of the object is assumed to be greater 
  than that of the creating or accessing application, so that in addition to maintaining 
  recovery information StateManager will attempt to automatically load (unload) 
  any existing persistent state for the object by calling the activate (deactivate) 
  operation at appropriate times. Finally, objects may possess none of these capabilities, 
  in which case no recovery information is ever kept nor is object activation/deactivation 
  ever automatically attempted.</p>
				<p>According to the its activation or deactivation a transactional object for 
  Java move from a passive state to an active state and vice-versa. The fundamental 
  life cycle of a persistent object in TXOJ is shown in Figure 2. </p>
				<p>
					<img src="includes/txoj_lifecycle.GIF"/>
				</p>
				<p>Figure 2 - The life cycle of a persistent object.</p>
				<ul>
					<li> The object is initially passive, and is stored in the object store as an 
    instance of the class OutputObjectState.</li>
					<li> When required by an application the object is automatically activated by 
    reading it from the store using a read_committed operation and is then converted 
    from an InputObjectState instance into a fully-fledged object by the restore_state 
    operation of the object.</li>
					<li> When the application has finished with the object it is deactivated by 
    converting it back into an OutputObjectState instance using the save_state 
    operation, and is then stored back into the object store as a shadow copy 
    using write_uncommitted. This shadow copy can be committed, overwriting the 
    previous version, using the commit_state operation. The existence of shadow 
    copies is normally hidden from the programmer by the transaction system. Object 
    de-activation normally only occurs when the top-level transaction within which 
    the object was activated commits.</li>
				</ul>
				<p>While deactivating and activating a transactional object for java, the operations 
  save_state and restore_state are respectively invoked. These operations must 
  be implemented by the programmer since StateManager cannot detect user level 
  state changes. This gives the programmer the ability to decide which parts of 
  an object&#8217;s state should be made persistent. For example, for a spreadsheet 
  it may not be necessary to save all entries if some values can simply be recomputed. 
  The save_state implementation for a class Example that has two integer member 
  variables called A and B and one String member variable called C could simply 
  be:</p>

<pre>public boolean save_state(OutputObjectState o)
{
   if (!super.save_state(o))
      return false;
   try
   {
     o.packInt(A);
     o.packInt(B);
     o.packString(C));
   }
   catch (Exception e)
   {
     return false;
   }
   return true;
}</pre>

				<p>while, the corresponding restore_state implementation allowing to retrieve 
  similar values is:</p>

<pre>public boolean restore_state(InputObjectState o)
{
   if (!super.restore_state(o))
      return false;
   try
   {
     A = o.unpackInt();
     B = o.unpackInt();
     S = o.unpackString());
   }
   catch (Exception e)
   {
     return false;
   }
   return true;
}
</pre>

				<p>Classes OutputObjectState and InputObjectState provide respectively operations 
  to pack and unpack instances of standard Java data types. In other words for 
  a standard Java data type, for instance Long or Short, there are corresponding 
  methods to pack and unpack, i.e., packLong or packShort and unpackLong or unpackShort. 
</p>
				<p>
					<strong>Note:</strong> it is necessary for all save_state and restore_state 
  methods to call super.save_state and super.restore_state. This is to cater for 
  improvements in the crash recovery mechanisms.</p>
				<h4>The concurrency controller</h4>
				<p> The concurrency controller is implemented by the class LockManager which provides 
  sensible default behaviour while allowing the programmer to override it if deemed 
  necessary by the particular semantics of the class being programmed. The primary 
  programmer interface to the concurrency controller is via the setlock operation. 
  By default, the runtime system enforces strict two-phase locking following a 
  multiple reader, single writer policy on a per object basis. However, as shown 
  in Figure 1, by inheriting from the Lock class it is possible for programmers 
  to provide their own lock implementations with different lock conflict rules 
  to enable type specific concurrency control.</p>
				<p> Lock acquisition is (of necessity) under programmer control, since just as 
  StateManager cannot determine if an operation modifies an object, LockManager 
  cannot determine if an operation requires a read or write lock. Lock release, 
  however, is under control of the system and requires no further intervention 
  by the programmer. This ensures that the two-phase property can be correctly 
  maintained.</p>

<pre>public abstract class LockManager extends StateManager
{
   public LockResult setlock (Lock toSet, int retry, int timeout);
};</pre>

				<p> The LockManager class is primarily responsible for managing requests to set 
  a lock on an object or to release a lock as appropriate. However, since it is 
  derived from StateManager, it can also control when some of the inherited facilities 
  are invoked. For example, LockManager assumes that the setting of a write lock 
  implies that the invoking operation must be about to modify the object. This 
  may in turn cause recovery information to be saved if the object is recoverable. 
  In a similar fashion, successful lock acquisition causes activate to be invoked.</p>
				<p> The code below shows how we may try to obtain a write lock on an object:</p>
<pre>public class Example extends LockManager
{
   public boolean foobar ()
   {
     AtomicAction A = new AtomicAction;
     /*
     <strong>
     * The ArjunaCore AtomicAction class is here used to create 
     * a transaction. Any interface provided by the JTA or 
     * JTS interfaces that allow to create transactions can 
     * be used in association with the Locking mechanisms 
     * described in this trail.</strong>
     */
     boolean result = false;

     A.begin();
     if (setlock(new Lock(LockMode.WRITE), 0) == Lock.GRANTED)
     {
       /*
       * Do some work, and TXOJ will
       * guarantee ACID properties.
       */
       // automatically aborts if fails
       if (A.commit() == AtomicAction.COMMITTED)
       {
         result = true;
       }
     }
    else
       A.rollback();

    return result;
   }
}
</pre>
				<h4>Further Reading</h4>
				<p>More details on Transactional Object For Java can be found in the ArjunaCore 
  Programming Guide.<br/>
				</p>
			</html>
		</area>
	</content>
	<footer/>
</page>
