JOTM design is very similar to OTS specification (JOTM started as an OTS implementation). However, it is not an implementation of OTS and several parts of its design changed significantly from OTS.
JOTM core interfaces are very similar to OTS (most changes are the
type of exception being thrown, RemoteException for JOTM interfaces to
conform to RMI):
In addition JOTM depends on JTA interfaces:
The most confusing aspect of JOTM is the use of both Resource and
XAResource interfaces at different level in the code.
This comes from the way JOTM handles distribution and deals
with resource managers (RDBMS, MOM, EIS,...)
JOTM relies only on XAResource objects to deal with Resource Managers.
All systems supporting distributed transactions (JDBC, JMS, J2EE
Connectors) do so by providing an implementation of XAResource
interface.
Thus, the transaction manager can treat the different resource
managers uniformally through the use of the XAResource.
However, XAResource is not a remote interface and can't be access
through RMI.
So if the transaction is using XAResources located on different JVM,
JOTM can't directly use XAResources. It need a way to communicate
remotely with them.
Enter the Resource interface.
The Resource interface is almost identical to OTS
Resource interface
(it only adds RemoteException throwing to method signatures).
JOTM communicates remotely with the different XAResources using
Resource objects.
In fact, one Resource object is used to communicate with the
different XAResource on a given JVM.
To sum up:
XAResource
objects.Resource
objectsA quick look at JOTM classes highlights the presence of the same methods (prepare/commit/rollback or variations like doPrepare and so on) in different objects with no clear relations between them. Such objects are:
ControlImpl (implements Terminator
and Resource)Current (implements UserTransaction
and TransactionManager)SubCoordinator (implements Resource)TransactionImpl (implements Transaction)XAResourceThere is a strict hierarchy between these objects as they are all involved in the 2 Phace Commit but at different level:
Current and
TransactionImplControlImplSubCoordinatorXAResourceUserTransaction and TransactionManagerbegin,
[commit,rollback])XAResource are in the same JVM) or distributed
(XAResources in different JVMs)ResourceXAResourcesTerminatorResources (mostly implemented by
SubCoordinator) How is the JOTM 2PC engine designed?
Which bjects are involved in a 2PC?
Current.commit()Current delegates commit() to the Transaction object
associated with the current thread (represented by
TransactionImpl).Resource)SubCoordinator manages the local 2PC and its
XAResourcesControlImpl calls prepare() on its Resources
(i.e. SubCoordinators)SubCoordinator calls prepare() on its
XAResources and returns the
overall vote to ControlImplControlImpl's Resource
voted OK (i.e all
SubCoordinators' XAResources voted
XA_OK)ControlImpl calls commit() on its ResourcesSubCoordinators calls commit() on its
XAResourcesControlImpl calls rollback() on its ResourcesSubCoordinators calls rollback() on its
XAResourcesIt is to be noted that a local transaction can be seen as an
optimization of a distributed transaction with only one remote
Resource which happens to be in the same JVM.
So we can avoid the remote call to ControlImpl and just call
SubCoordinator_commit_one_phase() (this method
corresponds to the remote 1PC but it will handle the local 2PC with the local
XAResources.
The hierarchy of call on the objects during the 2PC is:
Current
\
TransactionImpl
\
ControlImpl
// skipped if transaction is local.
// manage 2PC on remote Resources.
\
SubCoordinator
// local transaction.
// manage 2PC on local XAResources.
\
XAResource