ONJava.com -- The Independent Source for Enterprise Java
oreilly.comSafari Books Online.Conferences.

advertisement

AddThis Social Bookmark Button

J2EE Transaction Frameworks, Part 3
Pages: 1, 2, 3, 4

Local transaction management

Transactions are specified and handled either by the container (container-managed demarcation) or by a component (component-managed demarcation). In component managed demarcation, an application component can use the JTA UserTransaction interface or a transaction demarcation API specific to an EIS (for example, JDBC transaction demarcation using java.sql.Connection). The EJB specification requires an EJB container to support both container-managed and component-managed transaction demarcation models. The JSP and servlet specifications require a web container to support component-managed transaction demarcation. The requirements demanded from a resource manager and a transaction manager for the transaction management contract are as follows.

  • Resource Manager
    A resource manager can be classified based on the level of transaction support, as follows.



    • NO_TRANSACTION: The resource manager supports neither resource manager local nor JTA transactions. It implements neither XAResource nor LocalTransaction interfaces.
    • LOCAL_TRANSACTION: The resource manager supports local transactions by implementing the LocalTransaction interface as defined in the specification.
    • XA_TRANSACTION: The resource manager supports both local and JTA transactions by implementing LocalTransaction and XAResource interfaces respectively.
  • Application Server
    An application server is required to support resource managers with all three levels of transactional support, namely, NO_TRANSACTION, LOCAL_TRANSACTION and XA_TRANSACTION.

    • The application server is required to support a transaction manager that manages transactions using the JTA XAResource-based contract.
    • The application server is required to use the LocalTransaction interface-based contract to manage local transactions for a resource manager.
    • The application server is required to use the deployment descriptor mechanism to ascertain the transactional capabilities of a resource adapter.
    • The application server is required to implement the javax.resource.spi.ConnectionEventListener interface to get transaction-related event notifications.
    • The application server is required to support a connection sharing mechanism.

The table below shows the typical combinations one is likely to encounter with transaction managers built into an application server and resource managers. Only the recommended options are shown in the cells. When multiple resource managers participate in a transaction, the EJB container uses a transaction manager to coordinate the transaction. The contract between the transaction manager and resource manager is defined using the XAResource interface. So, if a single resource manager instance participates in either a container-managed or component-managed transaction, the container can choose to do one of the following.

 

Resource Manager

NO_TRANSACTION

Resource Manager

LOCAL_TRANSACTION

Resource Manager

XA_TRANSACTION

App Server

NO_TRANSACTION

-

Use RML Tran

Use RML Tran

App Server

LOCAL_TRANSACTION

Use Local JTA

Use RML Tran

Use RML Tran

App Server

XA_TRANSACTION

Use Local JTA

Use RML Tran

Use JTA/XA Tran

  • The EJB container uses the transaction manager to manage the transaction. The transaction manager uses one-phase commit optimization to coordinate the transaction for this single resource manager instance as there is no other resource manager involved.

  • The EJB container lets the resource manager of the single resource participating in this transaction take control and coordinate it internally without involving an external transaction manager of the container. If an application accesses a single resource manager using a JTA/XA transaction, it has a performance overhead as opposed to using local transactions. The overhead is due to the involvement of an external transaction manager in the coordination of the JTA/XA transaction. To avoid the overhead of using an JTA/XA transaction in a single resource manager scenario, the application server may optimize by using a local transaction instead of a JTA/XA transaction. This scenario is shown in the figure below.

Diagram.
Figure 7 Local Transaction on a single Resource Manager

Local transaction scenarios

A resource manager local transaction is specific to a particular resource (RDBMS or EIS) connection and is completely managed by the underlying resource manager. The application server with its EJB container and built-in transaction manager has neither any control nor knowledge about any local transactions started by application components. The typical cases when local transactions are involved fall into the following categories.

  • If no JTA transaction has been initiated, access to a transactional enterprise information system will be under the control of a local transaction. For example, if an RDBMS is accessed via JDBC from a web component like a servlet without starting a JTA transaction, it will be under the scope of a local transaction specific to that RDBMS.
  • The other scenario where scope of local transaction comes into play is when the RDBMS or the EIS is not supported by the J2EE platform. A standard J2EE platform, for example, is not required to support object-oriented databases. As a result, the platform would not be able to propagate any JTA transactions to the object-oriented databases and any access will be under the control of local transactions specific to that object oriented database system.

Compensating Transactions

The only way to undo the effect of a mistake made in a transaction is to run another transaction to invert the prior effect of the committed transaction. A compensating transaction is such a group of operations constituting a transaction used to undo the effect of a previously committed transaction. There are instances where multiple accesses to enterprise information systems need to be grouped under a single transaction but not all of the systems support JTA transactions. In such cases it is necessary to define a compensating transaction for each enterprise information system access that is under the scope of a local transaction. If a component needs to access an enterprise information system that does not support JTA transactions or access an enterprise information system that is not supported by a particular J2EE platform, compensating transactions need to be defined.

In such cases the enterprise information systems are accessed under the scope of resource manager local transactions. If multiple enterprise information systems are involved, this creates the challenge of having to group all the work to multiple enterprise information systems into an atomic unit. For example, suppose an application needs to perform an atomic operation that involves updating three enterprise information systems: two JDBC databases that supports JTA transactions and an enterprise resource planning system that does not. The application would need to define a compensating transaction for the update to the enterprise resource planning system. The approach is illustrated in the following example.

updateEIS();
try {
UserTransaction.begin();
UpdateJDBC_RDBMS1();
UpdateJDBC_RDBMS2();
UserTransaction.commit();
}
catch (RollbackException ex) {
undoUpdateEIS();
}

Compensating transaction

The methods updateEIS(), updateJDBC_RDBMS1(), and updateJDBC_RDBMS2() have implementations to perform work on the EIS, RDBMS1 and RDBMS2 respectively. The undoUpdateEIS() method implements the logic to undo the effect of updateEIS() in case one of the JTA transactions involving RDBMS1 or RDBMS2 does not commit successfully. Ideally this kind of implementation of compensation logic should be encapsulated in a session bean with bean-managed transaction. The transaction attribute of such a session bean should be set to NotSupported if its only responsibility is to access an enterprise information system that does not support JTA transactions. Finally, there are a few important observations that one needs to be careful about in compensating transactions.

  • It may not always be possible to undo the effect of a committed transaction by using compensation logic. Consider what would happen in the example above if one of the JTA transactions does not commit and for some reason the method undoUpdateEIS() does not succeed!

  • In case of a server crash there would be a violation of the atomicity property when a compensating transaction is used. For example, if the system crashes after the method updateEIS(), the updates to the two databases will not take place.

  • It is possible that an inconsistent state of data is visible due to concurrent enterprise information system access since local resource manager transactions are actually committed but undone subsequently. In the previous example, a concurrent enterprise in-formation system access might see the update to the enterprise resource planning system, i.e., uncommitted data which might be rolled back later.

In order to deal with all sorts of potential failures and inconsistencies, any application using compensating transactions must have extra logic implemented. Because of all the complexity and drawbacks of using compensating transactions it should be avoided unless there is no other way to deal with such situations. It is strongly recommended to use JTA/XA transactions as they provide a simple and safe way to achieve the ACID properties across multiple components in multiple tiers accessing multiple relational database management systems or enterprise information systems.

Conclusion

This series has barely scratched the surface of a very complex topic encountered in everyday distributed enterprise computing environments. Although some of the core technologies have been around for a while, there is a resurgence of interest with the advent of the large scale web applications being developed in enterprises.

It's important to understand the choices one needs to make in choosing an application server so that it can work seamlessly with resource managers to provide the best transactional robustness and performance. The key questions to be asked while designing such a system concern which industry standard interfaces are implemented by both the transaction manager (built into the application servers) and the resource managers.

Dibyendu Baksi is a J2EE transactions systems and frameworks designer and developer for Sun Microsystems, Inc.


Return to ONJava.com.