JTA/JTS Architecture
The Java transaction initiative consists of two specifications: Java Transaction Service (JTS) and Java Transaction API (JTA).
JTS specifies the implementation of a Java transaction manager. This
transaction manager supports the JTA, using which application servers can
be built to support transactional Java applications. Internally the JTS
implements the Java mapping of the OMG OTS specifications.
The JTA specifies an architecture for building transactional
application servers and defines a set of interfaces for various components
of this architecture. The components are: the application, resource managers,
and the application server, as shown in the slide.
The JTS thus provides a new architecture for transactional application
servers and applications, while complying to the OMG OTS 1.1 interfaces
internally. This allows the JTA compliant applications to interoperate
with other OTS 1.1 complaint applications through the standard IIOP.
As shown in the Figure 1, in the Java transaction model, the Java application
components can conduct transactional operations on JTA compliant resources via
the JTS. The JTS acts as a layer over the OTS. The applications can therefore
initiate global transactions to include other OTS transaction managers, or participate
in global transactions initiated by other OTS compliant transaction managers.
Figure 1 - The JTA/JTS transaction model
The Java Transaction Service is architected around an application server and
a transaction manager. The architecture is shown in Figure 2.
Figure 2 - The JTA/JTS Architecture
The JTS architecture consists of the following components:
-
Transaction Manager: The transaction manager is the core component
of this architecture and is provided by an implementation of the JTS. It
provides interfaces to create transactions (including transaction demarcation
and propagation of transaction context), allows enlistment and delistment
of resources, provides interfaces for registering components for application
synchronization, implements the synchronization protocol, and initiates
and directs the two phase commit and recovery protocol with the resource
managers.
-
Application Server: One of the key features of the JTS architecture
is that it allows an application server to be built on top of the transaction
service and the resources. Application developers can develop and deploy
application components onto the application server for initiating and managing
transactions. The application server can therefore abstract all transactional
semantics from the application programs.
-
Application Components: These are the clients for the transactional
resources and implement business transactions. These are deployed on the
application server. Depending on the architecture of the application server,
these components can directly or indirectly create transactions and operate
on the transactional resources. For example, an Enterprise JavaBean (EJB)
server allows declarative transaction demarcation, in which case, the EJB
components need not directly implement the transactions. However, a Java
implementation of a CORBA OTS, requires the CORBA object to demarcate transactions
explicitly.
-
Resource Manager: A resource manager is an X/Open XA compliant component
that manages a persistent and stable storage system, and participates in
the two phase commit and recovery protocol with the transaction manager.
The application manager also provides interfaces for the application server
and the application components to operate on the data managed by it.
-
Communication Resource Manager: This allows the transaction manager
to participate in transactions initiated by other transaction managers.
However, the JTS specification does not specify any protocol for this communication
and assumes that an implementation of the communication resource manager
supports the CORBA OTS and GIOP specifications.
Java Transaction API
The JTA specification may be classified into three categories of interface
as shown in Figure 3. The Java Transaction API consists of three elements:
a high-level application transaction demarcation interface, a high-level
transaction manager interface intended for application server, and a standard
Java mapping of the X/Open XA protocol intended for transactional resource
manager.
Figure 3 - JTA Interfaces
Transaction Manager Interfaces
- javax.transaction.Status: Defines the following flags for the status of
a transaction:
Flag
|
Purpose
|
STATUS_ACTIVE |
Transaction is active (started but not prepared) |
STATUS_COMMITTED |
Transaction is committed |
STATUS_COMMITTING |
Transaction is in the process of committing. |
STATUS_MARKED_ROLLBACK |
Transaction is marked for rollback. |
STATUS_NO_TRANSACTION |
There is no transaction associated with the current Transaction, UserTransaction
or TransactionManager objects. |
STATUS_PREPARED |
Voting phase of the two phase commit is over and the transaction is prepared. |
STATUS_PREPARING |
Transaction is in the process of preparing. |
STATUS_ROLLEDBACK |
Outcome of the transaction has been determined as rollback. It is likely
that heuristics exists. |
STATUS_ROLLING_BACK |
Transaction is in the process of rolling back. |
STATUS_UNKNOWN |
A transaction exists but its current status can not be determined. This
is a transient condition |
Table 1: Transaction Status Flags
The javax.transaction.Transaction, javax.transaction.TransactionManager, and javax.transaction.UserTransaction
interfaces provide a getStatus method that returns one of the above status flags.
-
javax.transaction.Transaction:
An object of this type is created for each global transaction. This interface
provides methods for transaction completion(commit and rollback), resource
enlistment (enlistResource) and delistment (delistResource), registration
of synchronization objects (registerSynchronization), and query of status
of the transaction (getStatus).
-
javax.transaction.TransactionManager:
This interface is implemented by the JTS and allows an application server
to communicate with the transaction manager to demarcate transactions (begin,
commit, rollback), suspending and resuming transactions (suspend and resume),
set the transaction for rollback (setRollbackOnly), get the associated
Transaction object (getTransaction), set the transaction timeout interval
(setTransactionTimeout) and query the status of the transaction (getStatus).
-
javax.transaction.UserTransaction:
. This interface provides methods to begin and end transactions (begin,
commit, and rollback), set the transaction for rollback (setRollbackOnly),
set the transaction timeout interval (setTransactionTimeout), and get the
status of the transaction (getStatus). Nested transactions are not supported,
and begin throws the NotSupportedException when the calling thread is already
associated with a transaction. UserTransaction automatically associates
newly created transactions with the invoking thread.
-
javax.transaction.xa.Xid: This
interface is a Java mapping of the X/Open transaction identifier xid structure.
The transaction manager uses an object of this type to associate a resource
manager with a transaction.
Resource Manager Interfaces
-
javax.transaction.xa.XAResource:
This is a Java mapping of the X/Open XA interface, and is implemented by
resource managers operating with the JTS. This interface provides methods
to start (start) and end (end) work on behalf of a specified transaction,
to prepare a transaction with the current resource (prepare), to end transactions
with the current resource (commit, forget, recover, and rollback), to compare
the current resource manager with another resource manager (isSameRM),
and to get and set the transaction timeout (getTransactionTimeout, setTransactionTimeout).
Application Interfaces
The only interface that an application object could implement is the Synchronization
interface. The application components may have to implement whatever other
interfaces are mandated by a given application server.
-
javax.transaction.Synchronization:
An object intended to participate in a synchronization protocol with the
transaction manager should implement this interface. This mechanism is
based on the Observer pattern. This interface has two methods - beforeCompletion
and afterCompletion to be called before starting and after completing,
respectively, the two phase commit operation.
Java Transaction API - Usage
This section describes the usage of the JTA for implementing various transaction
semantics. The purpose of this section is to provide conceptual guidelines
only.
Transaction Demarcation
The JTA specifies two approaches with which new global transactions can
be initiated and demarcated.
-
Application Program Demarcation: The javax.transaction.UserTransaction
interface provides methods for application components to begin and end
transactions programmatically. The underlying application server should
provide a mechanism to obtain a reference to this object. The JTA specification
requires that the application servers use the JNDI for storing references
to UserTransaction objects and for lookup.
The application component can then use this object to begin, commit
and rollback transactions. In this approach, association between the calling
thread and the transaction, and transaction context propagation are handled
transparently by the transaction manager.
Usage:
// Get a UserTransaction object
// Begin a transaction
userTransaction.begin();
// Transactional operations ...
// End the transaction
userTransaction.commit();
- Application Server Controlled Demarcation In this approach, the javax.transaction.TransactionManager
interface controls transaction demarcation on behalf of the application being
managed. The transaction manager also maintains the transaction context and
its association with the calling threads implicitly.
Usage
// Begin a transaction
Transaction t = TransactionManager.begin();
// Transactional operations ...
// End the transaction
TransactionManager.commit();
Resource Enlistment and Delistment
Transactional resources such as database connections are typically managed by
the application server in conjunction with some resource adapter and optionally
with connection pooling optimisation. In order for an external transaction manager
to co-ordinate transactional work performed by the resource managers, the application
server must enlist and de-list the resources used in the transaction. These resources
(participants) are enlisted with the transaction so that they can be informed
when the transaction terminates, e.g., are driven through the two-phase commit
protocol.
The JTA is much more closely integrated with the XA concept of resources
than the arbitrary objects. For each resource in-use by the application,
the application server invokes the enlistResource method with an XAResource
object which identifies the resource in use.
The enlistment request results in the transaction manager informing
the resource manager to start associating the transaction with the work
performed through the corresponding resource. The transaction manager is
responsible for passing the appropriate flag in its XAResource.start method
call to the resource manager.
The delistResource method is used to disassociate the specified resource
from the transaction context in the target object. The application server
invokes the method with the two parameters: the XAResource object that
represents the resource, and a flag to indicate whether the operation is
due to the transaction being suspended (TMSUSPEND), a portion of the work
has failed (TMFAIL), or a normal resource release by the application (TMSUCCESS).
The de-list request results in the transaction manager informing the
resource manager to end the association of the transaction with the target
XAResource. The flag value allows the application server to indicate whether
it intends to come back to the same resource whereby the resource states
must be kept intact. The transaction manager passes the appropriate flag
value in its XAResource.end method call to the underlying resource manager.
The
application server can enlist and delist resource managers with the transaction
manager using the
javax.transaction.Transaction
interface
Usage
Resource enlistment is in general done by the application server when an application
requests it for a connection to a transactional resource.
// ... an implementation of the application server
// Get a reference to the underlying TransactionManager object.
...
// Get the current Transaction object from the TransactionManager.
transaction = transactionManager.getTransaction();
// Get an XAResource object from a transactional resource.
...
// Create a Transaction object.
...
// Enlist the resource
transaction.enlistResource(xaResource);...
// Return the connection to the application.
...
Resource delistment is done similarly after the application closes connections to transactional resources.
Application Synchronization with a Transaction
Using the JTS synchronization protocol, certain objects can be registered
with the transaction manager for notification before the start of and the
completion of the two-phase commit process. This enables such application
objects to synchronize transient state and data stored in persistent storage.
The javax.transaction.Transaction
interface provides the registerSynchronization method to register
javax.transaction.Synchronization
objects with the transaction manager. The transaction manager then uses
the synchronization protocol and calls the beforeCompletion and afterCompletion
methods before and after the two phase commit process.
-
The beforeCompletion method is called prior to the start of the
two-phase transaction complete process. This call is executed in the same
transaction context of the caller who initiates the TransactionManager.commit
or the call is executed with no transaction context if Transaction.commit
is used.
-
The afterCompletion method is called after the transaction has completed.
The status of the transaction is supplied in the parameter. This method
is executed without a transaction context.
Further Reading