Transaction Services with JTA and JTS
The primary OTS interfaces involved in encapsulating access to transactional objects, resources, and their coordination are shown in Figure 14.12. A transaction coordinator manages communication with transactional objects and resources that participate in transactions. Each interface of Figure 14.12 is described here:
TransactionalObject: This marker interface is implemented by those objects that want to participate in a transaction. An ORB will automatically propagate the transaction context of a client thread when a method on a TransactionalObject implementation is invoked.
Resource: The Resource interface is implemented by resources that participate in a two-phase commit protocol.
SubtransactionAwareResource: This sub-interface of the Resource interface is implemented by resources that participate in a two-phase commit protocol that employs a nested transaction model.
Coordinator: The Coordinator interface can be used to create transactions and manage their behavior, obtain transaction status and information, compare transactions, register resources and synchronization objects, and create subtransactions in a nested transaction.
RecoveryCoordinator: When a Resource is registered with the Coordinator, a RecoveryCoordinator handle is returned to enable the handling of certain recovery scenarios. The resource can ask the coordinator to replay the transaction completion sequence if it did not receive a transaction completion request within a certain transaction timeout.
OTS coordination, resource, and transactional object interfaces.
Figure 14.13 depicts those OTS interfaces used to create and manage transactions. We have already described the Coordinator interface, but the interfaces that rely on the Coordinator interface are also shown here. APIs such as the Current interface can be utilized by application programs to manage transactions at a higher level. The transaction management interfaces depicted in Figure 14.13 are described here:
Terminator: A Terminator interface is used to commit or rollback a transaction. Thus, although a transaction may have been created by another application, this interface provides a mechanism to terminate the transaction from another application.
Control: The Control interface provides a handle to manage a transaction context that can be propagated between applications. Can return a handle to a transaction coordinator or terminator to accomplish these tasks.
Current: Current is a frontline IDL interface for applications to use when creating transactions. Current provides operations to begin, commit, rollback, suspend, and resume transactions. The status of a transaction can also be obtained from the Current object. The current transaction context can be obtained from the initial ORB references.
TransactionFactory: A transaction can also be created with a TransactionFactory. Operations exist to create a new transaction with a particular timeout value and to re-create an existing transaction given a propagation context.
OTS transaction creation and management interfaces.
Java Transaction API
The Java Transaction Architecture (JTA) specifies standard interfaces for Java-based applications and application servers to interact with transactions, transaction managers, and resource managers (http://java.sun.com/products/jta/). The JTA model follows the basic X/Open DTP model described earlier in this chapter and in Chapter 2, as depicted in Figure 2.2. The main components of the JTA architecture are shown in Figure 14.14. The JTA components in this diagram are defined in both the javax.transaction and the javax.transaction.xa packages. Three main interface groupings of the JTA are also shown, including JTA transaction management, JTA application interfacing, and JTA XA resource management. The relation to the Java Transaction Service (JTS) is also shown in this diagram.
The JTA architecture.
JTA transaction management provides a set of interfaces utilized by an application server to manage the beginning and completion of transactions. Transaction synchronization and propagation services are also provided under the domain of transaction management. The JTA Transaction, TransactionManager, Synchronization, and Status interfaces all belong to the realm of JTA transaction management. An application server will typically implement a container environment within which enterprise application components can run and utilize the services of transaction management.
An application server environment such as J2EE can provide a declarative model for applications to utilize transaction management services. JTA application interfacing also provides a programmatic interface to transaction management for use by applications. An application uses the UserTransaction interface for this very purpose.
The X/Open XA resource management interface provides a standard means for transaction managers to interact with resources (for example, a DBMS) involved in a distributed transaction. A resource adapter, such as JDBC, implements the XAResource interface that is also used by an application server environment.
Finally, the Java mapping of OTS known as the JTS provides a lower-level interface to a distributed transaction service. A JTS implementation will propagate transaction context to other transaction managers via standard X/Open communications resource manager interfaces.
The JTA interfaces are required as a part of the J2EE and thus JTA application interfaces must be implemented by J2EE server products. No specific protocol for transaction propagation interoperability across J2EE servers has been defined. However, the J2EE v1.4 standards indicate that a future version of the J2EE specification will require OTS-based interfaces and therefore require standard protocol interoperability via IIOP.
JTA Transaction Manager Interface
The JTA supports a standard interface to transaction management services. An application server accesses these services primarily through the TransactionManager and Transaction interfaces. Figure 14.15 depicts these interfaces and two other key JTA interfaces utilized by an application server to interact with an underlying transaction manager.
JTA transaction management.
The Status interface defines a set of static constants that indicate the state of a transaction. The Synchronization interface is provided to enable notification before a commit is prepared (that is, beforeCompletion()) and after a commit or rollback operation is performed (that is, afterCompletion()). A call to Transaction.registerSynchronization() can register a Synchronization object with a transaction associated with a current thread so that the beforeCompletion() and afterCompletion() calls can be made by a transaction manager.
The Transaction interface, as the name implies, encapsulates a transaction. A Transaction is created by a transaction manager and enables operations to be invoked on a transaction that is associated with a target transactional object. A Transaction object can be told to commit or rollback by invoking the methods commit() or rollback(), respectively. A Transaction object can also be told to only enable rollbacks (that is, and no commits) to be performed on a transaction using the setRollbackOnly() call. The constant Status of a transaction can be obtained via a call to Transaction.getStatus(). You'll learn more about the enlistResource() and delistResource() methods in a subsequent section.
The TransactionManager interface is used by an application server to manage transactions for a user application. The TransactionManager associates transactions with threads. The methods begin(), commit(), and rollback() on a TransactionManager are called by an application server to begin, commit, and rollback transactions for a current thread, respectively. The TransactionManager also supports a setRollbackOnly() method to designate the fact that only a rollback will be supported for the current thread's transaction. A setTransactionTimeout() method also defines a timeout for a transaction in terms of seconds, and a getStatus() method returns the static constant Status of the current thread's transaction.
A handle to the current thread's transaction can be obtained by calling TransactionManager.getTransaction(). By calling TransactionManager.suspend(), you can suspend the current transaction and also obtain a handle to the Transaction object. The TransactionManager.resume() method can resume the current transaction.
JTA Application Interface
The JTA application interface consists of the javax.transaction.UserTransaction Java interface, which is of most importance to an enterprise Java application developer. UserTransaction is used by an application to control transaction boundaries. Figure 14.16 depicts this interface and the relation between it, an application, and the underlying JTA transaction management architecture.
JTA user application interfacing.
The UserTransaction.begin() method can be called by an application to begin a transaction that gets associated with the current thread in which the application is running. An underlying transaction manager actually handles the thread to transaction association. A NotSupportedException will be thrown by the begin() call if the current thread is already associated with a transaction and there is no capability to nest the transaction.
The UserTransaction.commit() method terminates the transaction associated with the current thread. The UserTransaction.rollback() method induces an abort of the current transaction associated with the current thread. With a call to UserTransaction.setRollbackOnly(), the transaction associated with the current thread can only be aborted.
A timeout associated with the transaction can be set by calling UserTransaction.setTransactionTimeout() with an int value in seconds. Finally, the constant Status of a transaction can be yielded from the UserTransaction.getStatus() call.
J2EE application server components (that is, Enterprise JavaBeans) by and large can rely on the declarative and container-managed transaction semantics, but they also utilize the UserTransaction interface if it is desired to have the component programmatically manage its own transactions. Java Web components (that is, Java Servlets and JavaServer Pages) can also utilize the UserTransaction interface to demarcate transactions. Java Web components may look to using the UserTransaction interface directly when there is not an Enterprise JavaBeans tier involved with managing transactions or if the business logic for a particular set of transactional related actions are embedded directly within the Java Web components themselves. A handle to a UserTransaction may be gotten from a JNDI lookup or directly from the container environment in the case of Enterprise JavaBeans.
For example, you might retrieve the UserTransaction via JNDI using this:
UserTransaction trans = (UserTransaction) jndiContext.lookup("java:comp/UserTransaction");
Or an EJB may obtain the UserTransaction directly from the container context using this:
UserTransaction trans = containerContext.getUserTransaction();
The transaction can then be demarcated programmatically using this:
trans.begin(); // Do some work... // rollback if there is an issue... trans.rollback(); // commit if all was ok... trans.commit();
JTA and X/Open XA
The XA interface defined by the X/Open group (http://www.opengroup.org) specifies the interface to distributed resource managers as accessed by distributed transaction managers in the X/Open standard DTP model. The JTA encapsulates this interface using the XAResource and Xid interfaces depicted in Figure 14.17. The XAResource interface is utilized by a transaction manager to manage distributed transactions among resources.
JTA resource management interfaces.
Page 3 of 4