Java Reference
In-Depth Information
Pattern Variants
Two-phase commit - The transaction manager wants to be sure that all participants can commit before it calls
commit on them. So before calling commit, it first performs a voting round where each participant tells the
manager if it can commit (first phase). If one of the participants fails to be able to commit, the transaction will be
cancelled and cancel will be called on all the participants (roll-back is performed). When all participants agree,
commit will be called (second phase).
The difference is the pre-commit phase, which checks if everybody can commit and which signals all the
participants that the next signal will either be a cancel or a commit.
Optimistic versus conservative transactions - There are two approaches to implementing transactions: optimistic
and conservative. This choice has to be made at almost every point in the implementation. Pure forms only rarely
exist.
The basic difference is that in the optimistic approach, the participants can always join, but may not always be
able to commit. While in the conservative approach, the join may fail, but when joined, the participant can always
commit.
One of the other differences is in the way these approaches join transactions. In the conservative approach, the
client first has to call join on the participant to join in a specific transaction before any sensitive methods can be
called. In the optimistic way the participant will do the join for the client if this has not been done yet.
Related Patterns
None.
Example
Note:
For a full working example of this code example, with additional supporting classes and/or a
RunPattern
class,
The Personal Information Manager stores appointments based on their date. Naturally, since users lead active
lives, appointments change all the time. A user's appointment book is constantly being updated with new or
changing appointments.
If a number of users need to agree on a date for an appointment, it would be helpful if their appointment topics
could coordinate, arriving at a date that would work for everybody. That's what this example demonstrates—how
the Transaction pattern can be used to allow address books to reschedule a date for an appointment.
The basic interface that supports transactions is
AppointmentTransactionParticipant
. It defines three
methods to manage transactions (
join
,
commit
, and
cancel
) and the business method
changeDate
. This class is
a
Remote
class, since it is used to communicate between transaction participants that might reside on different
Java Virtual Machines.
Example 4.29
AppointmentTransactionParticipant.java
1. import java.util.Date;
2. import java.rmi.Remote;
3. import java.rmi.RemoteException;
4. public interface AppointmentTransactionParticipant extends Remote{
5. public boolean join(long transactionID) throws RemoteException;
6. public void commit(long transactionID) throws TransactionException, RemoteException;
7. public void cancel(long transactionID) throws RemoteException;
8. public boolean changeDate(long transactionID, Appointment appointment,
9. Date newStartDate) throws TransactionException, RemoteException;
10. }
The class
AppointmentBook
represents a user's calendar, and implements the
AppointmentTransactionParticipant
interface. In addition to providing support to change an
Appointment
date, the
AppointmentBook
can initiate a change of an
Appointment. Its method
changeAppointment
accepts a
transaction ID, an
Appointment
object, an array of other
AppointmentBooks
that should be transaction