CONTENTS | PREV | NEXT | INDEX Designing Enterprise Applications
with the J2EETM Platform, Second Edition



8.7 EIS Tier Transactions

Most enterprise information systems support some form of transactions. For example, a typical JDBC database allows multiple SQL updates to be grouped in an atomic transaction.

Components should always access an enterprise information system within the scope of a transaction to guarantee the integrity and consistency of the underlying data. Such systems can be accessed within a JTA transaction or a resource manager local transaction.


8.7.1 JTA Transactions

When an enterprise information system is accessed within the scope of a JTA transaction, any updates performed on the system will commit or roll back depending on the outcome of the JTA transaction. Multiple connections to information systems can be opened and all updates through the connections will be atomic if they are performed within the scope of a JTA transaction. The J2EE server is responsible for coordinating and propagating transactions between the server and the enterprise information system.

If the J2EE product supports multiple enterprise information systems in one transaction, a J2EE application can access and perform updates on multiple enterprise information systems atomically, without extra programming effort, by grouping all updates within a JTA transaction. Code Example 8.3 illustrates this use:

InitialContext ic = new InitialContext("java:comp/env");
DataSource db1 = (DataSource) ic.lookup("OrdersDB"); // JDBC
ConnectionFactory db2 =
	(ConnectionFactory) ic.lookup("InventoryEIS"); // Connector CCI
java.sql.Connection con1 = db1.getConnection();
javax.resource.cci.Connection con2 = db2.getConnection();
UserTransaction ut = ejbContext.getUserTransaction();
ut.begin();
// perform updates to OrdersDB using connection con1
// perform updates to InventoryEIS using connection con2
ut.commit();
Code Example 8.3 Accessing Multiple Transactional Resources

8.7.2 Resource Manager Local Transactions

A resource manager local transaction (or local transaction) is a transaction specific to a particular enterprise information system connection. A local transaction is managed by the underlying enterprise information system resource manager. The J2EE platform usually does not have control of or knowledge about any local transactions begun by components. Access to a transactional enterprise information system is usually within a local transaction if no JTA transaction has been initiated. For example, if a servlet accesses a JDBC database without starting a JTA transaction, the database access will be within the scope of a local transaction, specific to the database.

Local transactions may also be used when the enterprise information system is not integrated using the Connector architecture. For example, if no Connector resource adapter is available for an object-oriented database, a J2EE server cannot propagate any JTA transactions to the object-oriented database, and any access will be within local transactions. For this reason, applications should use the Connector architecture to integrate enterprise information systems that are not included as part of the J2EE platform.


8.7.3 EIS Tier Transaction Guidelines

Enterprise information systems such as databases should be accessed within the scope of a JTA transaction. Transactional access guarantees data consistency and integrity, and ensures that work performed by multiple components through multiple enterprise information system connections is grouped as an atomic unit. It also groups as an atomic unit work performed on one or more independent enterprise information systems.

Where JTA transaction control is not possible, such as with resource managers that do not support the JTA, consider using resource manager local transactions with compensating transactions (see the next section). Keep in mind that each local transaction requires an explicit commit or rollback. In addition, components using local transactions need extra logic to deal with individual enterprise information system rollbacks or failures.


8.7.4 Compensating Transactions

A compensating transaction is a transaction or a group of operations that undoes the effect of a previously committed transaction. A distributed transaction may include both JTA transactions and resource manager local transactions, but local transactions require explicit management. JTA-enabled resource managers handle rollback automatically by simply discarding any changes made since a transaction began. But each resource manager local transaction requires a compensating transaction that can undo the local transactions effects in case a rollback occurs.

Compensating transactions are useful if a component needs to access an enterprise information system that either does not support full JTA transactions or is not supported by a particular J2EE product. The J2EE platform supports JTA transactions for JDBC and JMS access. JTA transaction support for EIS access is determined by the transaction level of the resource adapter (see Section 8.8.3 on page 274). An XATransaction resource adapter automatically supports JTA transactions.

A LocalTransaction resource adapter (see Section 8.8.3 on page 274) accesses an EIS within the scope of a resource manager local transaction. Performing atomic operations on multiple EISs can be challenging when some of those systems do not participate in the JTA transaction. Compensating transactions meet this challenge by providing programmatic "rollback" of operations already committed by resource manager local transactions. Compensating transactions must be manually coded into application logic; the JTA provides no standard way to handle them.

For example, suppose an application needs to perform an atomic operation that involves updating two enterprise information systems: a database 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 Code Example 8.4.

updateERPSystem();
try {
	UserTransaction.begin();
	updateJDBCDatabase();
	UserTransaction.commit();
} 
catch (RollbackException ex) {
	undoUpdateERPSystem();
}
Code Example 8.4 Compensating Transaction

The methods updateERPSystem and updateJDBCDatabase contain code to access and perform work on enterprise information systems. The undoUpdateERPSystem method contains code to undo the effect of updateERPSystem if the JTA transaction does not commit successfully.

Compensating transactions have a few pitfalls:

8.7.4.1 Compensating Transaction Guidelines

Compensating transaction code should be encapsulated in a session enterprise bean with a bean-managed transaction. The session bean may implement all of the enterprise information system access logic itself, or delegate some or all of the access logic to other enterprise beans. If an enterprise bean's only responsibility is to access an enterprise information system that does not support JTA transactions, its transaction attribute should be set to NotSupported to indicate that a JTA transaction will not be used in the enterprise bean.

An application that depends on compensating transactions must have extra logic to deal with potential failures and inconsistencies. The extra work and pitfalls of compensating transactions mean applications should avoid using them when possible. Instead, use JTA transactions to simply and safely achieve ACID transaction properties across multiple components and enterprise information systems.


8.7.5 Isolation Level

An isolation level defines how concurrent transactions to an enterprise information system are isolated from one another. Enterprise information systems usually support the following isolation levels:

Isolation level and concurrency are closely related. The isolation level indicates the degree of responsibility given to the EIS for managing concurrent data access. A lower isolation level typically allows greater concurrency, at the expense of more complicated logic to deal with potential data inconsistencies. A higher isolation level typically allows simpler logic, at the expense of system performance due to internal EIS data locking to enforce ACID transaction properties. A useful guideline is to use the highest isolation level provided by enterprise information systems that gives acceptable performance.

For consistency, all enterprise information systems accessed by a J2EE application should use the same isolation level. The J2EE specification version 1.3 does not define a standard way to set isolation levels when an enterprise information system is accessed within JTA transactions. If a J2EE product does not provide a way to configure the isolation level, the enterprise information system default isolation level will be used. For most relational databases, the default isolation level is ReadCommitted.

The isolation level should not change within a transaction, especially if some work has already been done. Some enterprise information systems will force a commit if you attempt to change the isolation level.


8.7.6 Performance with Multiple Resource Managers

The J2EE platform provides distributed transaction support across multiple resource managers, including JDBC databases, JMS providers, and EISes. The performance impact of using multiple resource managers in the same transaction is an important concern. Typically, a transaction that accesses more than one resource manager uses the two-phase distributed commit protocol, resulting in additional transaction processing overhead. Distributed transactions also cause additional administrative overhead; for example, partial failures of in-doubt transactions must always be resolved. Therefore, an application should minimize the use of multiple resource managers in the same transaction where possible (for example, by consolidating data into one EIS). However, JTA transactions should definitely be used when accessing multiple transactional resources. The benefits of data integrity and ease of programming that JTA transactions provide definitely outweigh the additional overhead incurred by two-phase commit.



CONTENTS | PREV | NEXT | INDEX
Copyright © 2002 Sun Microsystems, Inc. All Rights Reserved.