Transaction management under J2EE 1.2
Explore your options for managing transactions
By Sanjay Mahapatra, JavaWorld.com, 07/14/00
A transaction can be defined as an indivisible unit of work comprised of several operations, all or none of which must be
performed in order to preserve data integrity. For example, a transfer of 00 from your checking account to your savings account
would consist of two steps: debiting your checking account by 00 and crediting your savings account with 00. To protect data
integrity and consistency -- and the interests of the bank and the customer -- these two operations must be applied together
or not at all. Thus, they constitute a transaction.
Properties of a transaction
All transactions share these properties: atomicity, consistency, isolation, and durability (represented by the acronym ACID).
- Atomicity: This implies indivisibility; any indivisible operation (one which will either complete fully or not at all) is said to be
atomic.
- Consistency: A transaction must transition persistent data from one consistent state to another. If a failure occurs during processing,
the data must be restored to the state it was in prior to the transaction.
- Isolation: Transactions should not affect each other. A transaction in progress, not yet committed or rolled back (these terms are explained at the end of this section), must be isolated from other transactions. Although several transactions
may run concurrently, it should appear to each that all the others completed before or after it; all such concurrent transactions
must effectively end in sequential order.
- Durability: Once a transaction has successfully committed, state changes committed by that transaction must be durable and persistent,
despite any failures that occur afterwards.
A transaction can thus end in two ways: a commit, the successful execution of each step in the transaction, or a rollback, which guarantees that none of the steps are executed due to an error in one of those steps.
Transaction isolation levels
The
isolation level measures concurrent transactions' capacity to view data that have been updated, but not yet committed, by another transaction.
If other transactions were allowed to read data that are as-yet uncommitted, those transactions could end up with inconsistent
data were the transaction to roll back, or end up waiting unnecessarily were the transaction to commit successfully.
A higher isolation level means less concurrence and a greater likelihood of performance bottlenecks, but also a decreased
chance of reading inconsistent data. A good rule of thumb is to use the highest isolation level that yields an acceptable
performance level. The following are common isolation levels, arranged from lowest to highest:
- ReadUncommitted: Data that have been updated but not yet committed by a transaction may be read by other transactions.
- ReadCommitted: Only data that have been committed by a transaction can be read by other transactions.
- RepeatableRead: Only data that have been committed by a transaction can be read by other transactions, and multiple reads will yield the
same result as long as the data have not been committed.
- Serializable: This, the highest possible isolation level, ensures a transaction's exclusive read-write access to data. It includes the
conditions of
ReadCommitted and RepeatableRead and stipulates that all transactions run serially to achieve maximum data integrity. This yields the slowest performance
and least concurrency. The term serializable in this context is absolutely unrelated to Java's object-serialization mechanism and the java.io.Serializable interface.
Transaction support under J2EE
The Java 2 Enterprise Edition (J2EE) platform consists of the specification, compatibility test suite, application-development
blueprints, and reference implementation. Numerous vendors provide application servers/implementations based on the same specification.
J2EE components are meant to be specification-centric rather than product-centric (they are built to a specification, rather
than around a particular application-server product). J2EE applications include components that avail of the infrastructural
services provided by the J2EE container and server, and therefore need to focus only on "business logic." J2EE supports flexible
deployment and customization in the target production environment, using declarative attributes provided by a deployment descriptor.
J2EE aims to protect IT efforts and reduce application-development costs. J2EE components may be built in-house or procured
from outside agencies, which can result in flexibility and cost benefits for your IT department.
Transaction support is an important infrastructural service offered by the J2EE platform. The specification describes the
Java Transaction API (JTA), whose major interfaces include javax.transaction.UserTransaction and javax.transaction.TransactionManager. The UserTransaction is exposed to application components, while the underlying interaction between the J2EE server and the JTA TransactionManager is transparent to the application components. The TransactionManager implementation supports the server's control of (container-demarcated) transaction boundaries. The JTA UserTransaction and JDBC's transactional support are both available to J2EE application components.