<?xml version='1.0'?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" 
               "http://docbook.org/xml/4.2/docbookx.dtd"
	       [
	       <!ENTITY copyright SYSTEM "copyright.xml">
	       ]>

<chapter title="Transactions" id="16">
<title>
Transactions
</title>

<tocchap>
<title>
Contents
</title>

<toclevel1>
<tocentry>
  <ulink url="#Introduction">Introduction</ulink>
</tocentry>
<tocentry>
  <ulink url="#Transactions">Transactions</ulink>
</tocentry>
<tocentry>
  <ulink url="#TransactionManager">TransactionManager</ulink>
</tocentry>
<tocentry>
  <ulink url="#TransactionParticipant">TransactionParticipant</ulink>
</tocentry>
<tocentry>
  <ulink url="#Mahalo">Mahalo</ulink>
</tocentry>
<tocentry>
  <ulink url="#Example">Example</ulink>
  <toclevel2>
  <tocentry>
    <ulink url="#PayableFileClassifierImpl">PayableFileClassifierImpl</ulink>
  </tocentry>
  <tocentry>
    <ulink url="#AccountsImpl">AccountsImpl</ulink>
  </tocentry>
  <tocentry>
    <ulink url="#Client">Client</ulink>
  </tocentry>
  </toclevel2>
</tocentry>
<tocentry>
  <ulink url="#Summary">Summary</ulink>
</tocentry>
</toclevel1>
</tocchap>

<abstract>
<para>
Transactions are needed to coordinate changes of state across multiple clients
and services. The Jini transaction model uses a simple model of transactions,
with details of semantics left to the clients and services. The Jini
distribution supplies a transaction manager that can be used.
</para>
</abstract>

<sect1>
<title id="Introduction">
Introduction
</title>

<para>
Transactions are a neccessary part of many distributed operations. Frequently
two or more objects may need to synchronize changes of state so that they all
occur, or none occur. This happens in situations such as control of ownership,
where one party has to give up ownership at the ``same'' time as another
asserts ownership. What has to be avoided is only one party performing the
action, which could result in either no owners or two owners.
</para>

<para>
The <emphasis>theory</emphasis> of transactions often talks about the ``ACID''
properties:
<dl>
  <dt>
    Atomicity
  </dt>
  <dd>
    All the operations of a transaction must take place, or none of them do
  </dd>

  <dt>
    Consistency
  </dt>
  <dd>
    The completion of a transaction must leave the participants in a
    ``consistent'' state, whatever  that means. For example, the number of
    owners of a resource must remain at one
  </dd>

  <dt>
    Isolation
  </dt>
  <dd>
    The activities of one transaction must not affect any other transactions
  </dd>

  <dt>
    Durability
  </dt>
  <dd>
    The results of a transaction must be persistent
  </dd>

</dl>
</para>

<para>
The <emphasis>practice</emphasis> of transactions is that they use the 
<emphasis>two-phase commit protocol</emphasis>. This requires that participants
in a transaction be asked to ``vote'' on a transaction. If all agree to go ahead,
then the transaction ``commits'', which is binding on all the participants.
If any ``abort''  during this voting stage then it forces abortion of the
transaction on all participants.
</para>

<para>
Jini has adopted the syntax of the two-phase commit method. It is up to the 
clients and services within a transaction to observe the ACID properties if they
desire. Jini essentially supplies the <emphasis>mechanism</emphasis> of
two-phase commit, and leaves the <emphasis>policy</emphasis> of meaning
to the participants in a transaction.
</para>
</sect1>

<sect1>
<title id="Transactions">
Transactions
</title>

<para>
Restricting Jini transactions to a two-phase commit model without associating
a particular semantics to this means that a transaction can be represented in
a simple way, just as a <code>long</code> identifier. This identifier is
obtained from a transaction manager, and will uniquely label the transaction
to that manager. (It is not guaranteed unique <emphasis>between</emphasis>
managers, though - unlike service ID's.) 
All participants in the transaction communicate   with the
transaction manager, using this identifier to label which transaction they
belong to.
</para>

<para>
The participants in a transaction may disappear; the transaction manager may
disappear. So transactions are managed by a lease, which will expire unless
it is renewed. When a transaction manager is asked for a new transaction it
returns a <code>TransactionManager.Created</code> object, 
containing the transaction identifier and lease:
<programlisting>
public interface TransactionManager {
    public static class Created {
        public final long id;
        public final Lease lease;
    }
    ...
}
</programlisting>
A <code>Created</code> object may be passed around between participants in the
lease. One of them will need to look after lease renewals. All the participants
will use the transaction identifier in communication with the transaction
manager.
</para>

</sect1>

<sect1>
<title id="TransactionManager">
TransactionManager
</title>

<para>
A transaction manager looks after the two-phase commit protocol for all the
participants in a transaction. It is responsible for creating a new
transaction by its <code>create()</code> method. Any of the participants
may force the transaction to abort by <code>abort()</code>, or can force
it to the two-phase commit stage by calling <code>commit()</code>.
<programlisting>
public interface TransactionManager {

    Created create(long leaseFor) throws ...;
    void join(long id, TransactionParticipant part,
              long crashCount) throws ...;
    void commit(long id) throws ...;
    void abort(long id) throws ...;
    ...
}
</programlisting>
</para>

<para>
When a participant joins a transaction, it registers a listener of type
<code>TransactionParticipant</code>. If any participant calls <code>commit()</code>,
the transaction manager starts the voting process using all of these listeners.
If all of these are prepared to commit, then the manager moves all of these
listeners to the commit stage. Alternatively, any of the participants may call
<code>abort()</code>, which forces all of the listeners to abort.
</para>

</sect1>

<sect1>
<title id="TransactionParticipant">
TransactionParticipant
</title>

<para>
When an object becomes a participant listener in a transaction, it allows the
transaction manager to call various methods
<programlisting>
public interface TransactionParticipant ... {

    int prepare(TransactionManager mgr, long id) throws ...;
    void commit(TransactionManager mgr, long id) throws ...;
    void abort(TransactionManager mgr, long id) throws ...;
    int prepareAndCommit(TransactionManager mgr, long id) throws ...;
}
</programlisting>
These are triggered by calls made upon the transaction manager.
For example, if one client calls the transaction manager to abort,
then it calls all the listeners to abort.
</para>

<para>
The ``normal'' mode of operation (that is, when nothing goes wrong with
the transaction) is for a call to be made on the transaction manager
to commit. It then enters the two-phase commit stage where it asks
each participant listener to firstly <code>prepare()</code> and then
to either <code>commit()</code> or <code>abort()</code>.
</para>


</sect1>

<sect1>
<title id="Mahalo">
Mahalo
</title>

<para>
Mahalo is a transaction manager supplied by Sun as part of the Jini
distribution. It can be used without change. It runs as a Jini service,
like <code>reggie</code>. If <code>LaunchAll</code> has been used
to start <code>reggie</code>, then it will also have started <code>mahalo</code>.
</para>

<para>
Mahalo implements the service <code>{TransactionManager</code>.

<!--
Just like all Jini services, it has two parts: the part that runs as
a server, needing its own set of class files in <code>mahalo.jar</code>,
and the set of class files that need to be available to clients in
<code>mahalo-dl.jar</code>. It also needs a security policy, an HTTP server
and log files. It can be started using a command line such as
<programlisting>
java  -Djava.security.policy=policy.all \
      -Dcom.sun.jini.mahalo.managerName=TransactionManager \
      -jar /home/jan/tmpdir/jini1_0/lib/mahalo.jar \
      http://`hostname`:8080/mahalo-dl.jar \
      /home/jan/projects/jini/doc/policy.all \
      /tmp/mahalo_log public &amp;   
</programlisting>
-->

</para>
</sect1>

<sect1>
<title id="Example">
Example
</title>

<para>
The classic use of transactions is to handle money transfers between accounts.
In this there are two accounts, one of which is debited and the other credited.
This is not too exciting as an example, so we shall try a more complex situation.
A service may decide to charge for its use. If a client decides this cost is
reasonable, it will first credit the service and then request that the service
be performed. The actual accounts will be managed by an accounts service, which
will need to be informed of the credits and debits that occur. A simple accounts model
is that the service gets, say, a customer ID from the client, and passes its
own ID and the customer ID to the accounts service which manages both accounts.
Simple, prone to all sorts of e-commerce issues that we have no intention of
going into, and similar to the way credit cards work! 
</para>

<para>
Figure <xref linkend="credit"/> shows the messages in a normal sequence diagram.
The client makes a call <code>getCost()</code> to the service, and receives
the <code>cost</code> in return. It then makes another call <code>credit()</code>
on the service, which makes a call <code>creditDebit()</code> on the accounts
before returning. The client then makes a final call <code>requestService()</code>
on the service and gets back a <code>result</code>.
<figure id="credit">
<graphic fileref="images/credit.gif" align="center"> </graphic>
<title>Sequence diagram for credit/debit</title>
</figure>
</para>

<para>
There are a number of problems with this that can benefit by use of a transaction
model. The steps of <code>credit()</code> and <code>creditDebit()</code> should
certainly be performed either both together or not at all. But in addition there is
the issue of the quality of the service: suppose the client is not happy with
the results from the service. It would like to reclaim its money, or better yet,
not spend it in the first case! So if we include the delivery of the service in
the transaction then there is the opportunity to for the client to abort the
transaction before it is committed. 
</para>
<para>
Figure <xref linkend="transactioncredit"/> shows the 
larger set of messages in the sequence diagram for ``normal'' execution.
As before, the client requests the cost from the service.
After getting this, it asks the transaction manager to create a transaction
and receives the transaction id. It then joins the transaction itself.
When it asks the service to credit an amount, the service also joins the
transaction. The service then asks the account to <code>creditDebit()</code>
the amount, and as part of this the account also joins the transaction.
The client then requests the service and gets the result. If all is fine,
it then asks the transaction manager to <code>commit()</code>, which triggers
the prepare and commit phase. The transaction manager asks each participant
to <code>prepare()</code> and if it gets satisfactory replies from each
it then asks each one to <code>commit()</code>.
<figure id="transactioncredit">
<graphic fileref="images/transactioncredit.gif" align="center"> </graphic>
<title>Sequence diagram for credit/debit with transactions</title>
</figure>
</para>

<para>
The points of failure in this transaction include
<orderedlist>
<listitem>
  The cost may be too high for the client. However, at this stage it has not
  created or joined a transaction, so this doesn't matter
</listitem>
<listitem>
  The client may offer too little by way of payment to the service. The service
  can signal this by joining the transaction and then aborting it. This will
  ensure that the client has to rollback the transaction. (Of course, it could
  instead throw a <code>NotEnoughPayment</code> exception - joining and aborting
  is used for illustrating transaction possibilities.)
</listitem>
<listitem>
  There  may be a time delay between finding the price and asking for the service.
  The price may have gone up in the meantime! The service would then abort the
  transaction, forcing the client and the accounts to rollback
</listitem>
<listitem>
  After the service is performed, the client may decide that the result was not
  good enough, and refuse to pay. Aborting the transaction at this stage would
  cause the service and accounts to rollback
</listitem>
<listitem>
  The accounts service may abort the transaction if sufficient client funds are
  unavailable
</listitem>

</orderedlist>
</para>

<sect2>
<title id="PayableFileClassifierImpl">
PayableFileClassifierImpl
</title>

<para>
The service is a version of the familiar file classifier that requires a payment
before it will divulge the MIME type for a file name. A bit unrealistic, perhaps,
but that doesn't matter for purposes here. There will be an interface
<code>PayableFileClassifier</code>, which extends the <code>FileClassifier</code>
interface. We will also make it extend the <code>Payable</code> interface, just in
case we want to charge for other services. In line with other interfaces, we shall
extend this to a <code>RemotePayableFileClassifier</code>, and then implement this
by a <code>PayableFileClassifierImpl</code>.
</para>

<para>
The <code>PayableFileClassifierImpl</code> can use the implementation of the
<code>rmi.FileClassifierImpl</code>, so we shall make it extend this class.
We also want it to be a participant in a transaction, so it must implement the
<code>TransactionParticipant</code> interface. This leads to the 
inheritance diagram of figure <xref linkend="payableFCImpl"/>, 
which isn't really as complex as it looks.
<figure id="payableFCImpl">
<graphic fileref="images/payableFCImpl.gif" align="center"> </graphic>
<title>Class diagram for transaction participant</title>
</figure>

</para>

<para>
The new elements in this hierarchy are firstly the interface <code>Payable</code>
<programlisting>
<?program "src/common/Payable.java"?>
</programlisting>

Extending this is the interface <code>PayableFileClassifier</code>. This will
be used by the client to search for the service
<programlisting>
<?program "src/common/PayableFileClassifier.java"?>
</programlisting>
with a simple extension to the remote form
<programlisting>
<?program "src/txn/RemotePayableFileClassifier.java"?>
</programlisting>

</para>

<para>
The implementation of this joins the transaction when <code>credit()</code>
is called. It is passed the transaction manager as one parameter to this call.
It then finds an <code>Accounts</code> service
from a known location (using e.g. unicast lookup),
registers the money transfer, and then performs the service. There is no real state
information kept by this implementation which is altered by the transaction.
When asked to <code>prepare()</code> by the transaction manager it can just return
<code>NOTCHANGED</code>. If there was state, the <code>prepare()</code> and
<code>commit()</code> methods would have more content.
The <code>prepareAndCommit()</code> method may be called by a transaction manager
as an optimisation, and the version given in this example follows the 
specification given in the Jini Transaction document.
</para>

<para>
When the implementation object joins the transaction, it must pass an object that the
transaction can make calls on. Since the transaction manager is running remotely this
means that the object passed to it must be a <emphasis>proxy</emphasis>. This means
that the implementation must prepare a proxy and pass it to the transaction manager.
On the other hand, the server that contains the service object needs to have a proxy
to register the service. We have seen this a few times before: the service implements
<code>ProxyAccessor</code> which allows the server to get the proxy from the service.
</para>

<para>
The service implementation is
<programlisting>
<?program "src/txn/PayableFileClassifierImpl.java"?>
</programlisting>

</para>

<para>
The server for this implementation uses the variation that it gets the service proxy
from the service:
<programlisting>
<?program "src/txn/FileClassifierServer.java" ?>
</programlisting>
</para>

</sect2>

<sect2>
<title id="AccountsImpl">
AccountsImpl
</title>

<para>
We shall assume that all accounts in this example are managed by a single
<code>Accounts</code> service, that knows about all accounts by a <code>long</code>
identifier. These should be stored in permanent form, and there should be proper
crash recovery mechanisms, <emphasis>etc</emphasis>. For simplicity, we shall
just have a hash table of accounts, with uncommitted transactions kept in a
``pending'' list. When commitment occurs, the pending transaction takes place.
</para>

<para>
The <code>Accounts</code> service joins the transaction when <code>creditDebit()</code>
is called. It is passed the transaction manager as a parameter in this call.
</para>

<para>
Figure <xref linkend="accounts"/> shows the accounts class diagram.
<figure id="accounts">
<graphic fileref="images/accounts.gif" align="center"> </graphic>
<title>Class diagram for Accounts</title>
</figure>
The <code>Accounts</code> interface is
<programlisting>
<?program "src/common/Accounts.java"?>
</programlisting>
and the implementation is
<programlisting>
<?program "src/txn/AccountsImpl.java"?>
</programlisting>


</para>

<para>
The server for this implementation is standard:
<programlisting>
<?program "src/txn/AccountsServer.java" ?>
</programlisting>
</para>

</sect2>

<sect2>
<title id="Client">
Client
</title>

<para>
The final component in this is the client which starts the transaction.
The simplest code for this would just use the blocking <code>lookup()</code>
method of <code>ClientLookupManager</code> to find first the service and
then the transaction manager. We use the longer way to show various other
ways of doing things. This implementation uses
a nested class which extends <code>Thread</code>. Because of this, it cannot 
extend <code>UnicastRemoteObject</code>, and so is not automatically exported.
In order to export itself, it has to call 
<code>UnicastRemoteObject.exportObject)</code>. This must be done before the
call to join the transaction, which expects a remote object.
<programlisting>
<?program "src/client/TestTxn.java"?>
</programlisting>

</para>
</sect2>
</sect1>

<sect1>
<title id="Summary">
Summary
</title>

<para>
Transactions are needed to coordinate changes of state across multiple clients
and services. The Jini transaction model uses a simple model of transactions,
with details of semantics left to the clients and services. The Jini
distribution supplies a transaction manager that can be used.
</para>
</sect1>

&copyright;
</chapter>
