Serialization and isolation levels

An isolation level defines how concurrent transactions
accessing a RDBMS or an EIS are isolated from one another for read
purposes. The following the isolation levels are generally supported
in any RDBMS or EIS. These levels are defined in the ANSI SQL92
standard in terms of three phenomena that must be prevented between
concurrent transactions.

Dirty reads: A transaction reads a row in a database table containing uncommitted changes from another transaction.

Nonrepeatable reads: A transaction reads a row in a database table, a second transaction changes the same row and the first transaction rereads the row and gets a different value.

Phantom reads: A transaction re-executes a query, returning a set of rows that satisfies a search condition and finds that another committed transaction has inserted additional rows that satisfy the condition.

Following are the descriptions of the isolation levels.

TRANSACTION_READ_UNCOMMITTED: The transaction can read uncommitted data, i.e., data being changed by another transaction concurrently.

TRANSACTION_READ_COMMITTED: This level results in the prevention of a transaction from reading uncommitted changes in other concurrent transactions. This level ensures that dirty reads are not possible.

TRANSACTION_REPEATABLE_READ: In addition to the prevention associated with TRANSACTION_READ_COMMITTED, this level ensures that reading the same data multiple times will receive the same value even if another transaction modifies the data. Methods with this isolation level, besides having the same behavior as TRANSACTION_READ_COMMITTED, can only execute repeatable reads.

TRANSACTION_SERIALIZABLE: The transaction has exclusive read and update privileges to data by locking it; other transactions can neither write nor read the same data. It is the most restrictive transaction isolation level and it ensures that if a query retrieves a result set based on a predicate condition and another transaction inserts data that satisfy the predicate condition, re-execution of the query will return the same result set.

Isolation level summary

Isolation Level

Dirty Read

Non Repeatable Read

Phantom Read

TRANSACTION_READ_UNCOMMITTED

YES

YES

YES

TRANSACTION_READ_COMMITTED

NO

YES

YES

TRANSACTION_REPEATABLE_READ

NO

NO

YES

TRANSACTION_SERIALIZABLE

NO

NO

NO

The table shown above summarizes the discussion. A lower level of
isolation allows greater concurrency at the expense of more
complicated logic to deal with potential data inconsistencies. A
useful guideline is to use the highest isolation level provided by the
RDBMS or the EIS that gives acceptable performance. Although the
TX_SERIALIZABLE attribute guarantees the highest level of data
integrity, it is offset by a performance trade-off because even simple
reads must wait in line. All RDBMS or EIS used by a J2EE
application should use the same isolation level for consistency
reasons since the current J2EE specification does not define a
standard way to set isolation levels when an EIS is accessed via JTA
transactions. If a J2EE product does not provide a way to configure
the isolation level, the RDBMS or EIS will use a default isolation
level, which for most of the relational databases is
TRANSACTION_READ_COMMITTED. It is strongly recommended not to change
the isolation level within a transaction, especially if some work has
already been done. Some enterprise information systems may even force
a commit if it is attempted to change the isolation level in the
middle of a transaction. They're mapped in JDBC to the static
variables defined in the java.sql.Connection interface.

JTA/XA Transactions

A transaction managed and coordinated by the J2EE platform is a JTA
or XA transaction. A J2EE product is required to support JTA
transactions according to the transaction requirements defined in the
J2EE specification. There are two ways to begin a JTA transaction. A
component can begin a JTA transaction explicitly using the JTA
javax.transaction.UserTransaction interface or it can
also be started implicitly or automatically by the EJB container if an
EJB bean uses container managed transaction specification. The main
benefit of using JTA transactions is the ability to seamlessly combine
multiple application components and RDBMS/EIS accesses into one single
transaction with a little coding effort. For example, if a component X
begins a JTA transaction and invokes a method of component Y, the
transaction will be propagated transparently from component X to Y by
the platform. Enterprise beans using container-managed transaction
demarcation will not need to begin or commit transactions
programmatically as the demarcation is handled automatically by the
EJB container itself. It is always recommended to access an RDBMS or
EIS within the scope of a JTA transaction. JTA allows applications to
access transaction management independent of any specific
implementation by specifying standard Java interfaces between a
transaction manager, the transactional application, the J2EE server,
and the resource managers.

OMG Object Transaction Service JTS specifies the
implementation of a transaction manager that supports JTA and
implements the Java mapping of the OMG Object Transaction Service
(OTS) 1.1 specification. JTS propagates transactions using IIOP. A JTS
transaction manager provides the services and management functions
required to support transaction demarcation, transactional resource
management, synchronization, and transaction context propagation. An
application component developer uses the JTA
UserTransaction interface to demarcate JTA transaction
boundaries in components. The JTS TransactionManager and
XAResource interfaces are low level APIs between a J2EE
server and enterprise information system resource managers and are not
intended to be used by applications. A J2EE platform might choose to
use a JTS implementation to support the transaction semantics defined
in J2EE specification. An example is the J2EE SDK. The JTS
implementation is transparent to J2EE components. Components should
never interact directly with JTS. Instead, they should use the JTA
UserTransaction interface for transaction
demarcation.