Transaction and JTA Overview


For the purpose of this discussion, we can define a transaction as a unit of work containing one or more operations involving one or more shared resources having ACID properties. ACID is an acronym for atomicity, consistency, isolation, and durability, the four important properties of transactions. The meanings of these terms are

  • Atomicity A transaction must be atomic. Either all the work done in the transaction must be performed or none of it must be performed. Doing part of a transaction is not allowed.

  • Consistency When a transaction is completed, the system must be in a stable and consistent condition.

  • Isolation Different transactions must be isolated from each other. The partial work done in one transaction is not visible to other transactions until the transaction is committed, and each process in a multiuser system can be programmed as if it was the only process accessing the system.

  • Durability The changes made during a transaction are made persistent when it is committed. When a transaction is committed, its changes are not lost, even if the server crashes afterward.

To illustrate these concepts, consider a simple banking account application. The banking application has a database with a number of accounts. The sum of the amounts of all accounts must always be zero. An amount of money, M, is moved from account A to account B by subtracting M from account A and adding M to account B. This operation must be done in a transaction, and all four ACID properties are important.

The atomicity property means both the withdrawal and deposit are performed as an indivisible unit. If, for some reason, both cannot be done, nothing is done.

The consistency property means that after the transaction, the sum of the amounts of all accounts must still be zero.

The isolation property is important when more than one bank clerk uses the system at the same time. A withdrawal or deposit could be implemented as a three-step process: First, the amount of the account is read from the database; second, something is subtracted from or added to the amount read from the database; and, finally, the new amount is written to the database. Without transaction isolation several bad things could happen. For example, if two processes read the amount of account A at the same time, and each independently added or subtracted something before writing the new amount to the database, the first change would be incorrectly overwritten by the last.

The durability property is also important. If a money transfer transaction is committed, the bank must trust that some subsequent failure cannot undo the money transfer.

Pessimistic and Optimistic Locking

Transactional isolation is usually implemented by locking whatever is accessed in a transaction. There are two different approaches to transactional lockingpessimistic locking and optimistic locking.

The disadvantage of pessimistic locking is that a resource is locked from the time it is first accessed in a transaction until the transaction is finished, making it inaccessible to other transactions during that time. If most transactions simply look at the resource and never change it, an exclusive lock might be overkill as it can cause lock contention, and optimistic locking might be a better approach. With pessimistic locking, locks are applied in a fail-safe way. In the banking application example, an account is locked as soon as it is accessed in a transaction. Attempts to use the account in other transactions while it is locked either result in the other process being delayed until the account lock is released, or the process transaction being rolled back. The lock exists until the transaction has either been committed or rolled back.

With optimistic locking, a resource is not actually locked when it is first accessed by a transaction. Instead, the state of the resource at the time when it would have been locked with the pessimistic locking approach is saved. Other transactions are able to concurrently access the resource and the possibility of conflicting changes is higher. At commit time, when the resource is about to be updated in persistent storage, the state of the resource is read from storage again and compared to the state saved when the resource was first accessed in the transaction. If the two states differ, a conflicting update was made, and the transaction is rolled back.

In the banking application example, the amount of an account is saved when the account is first accessed in a transaction. If the transaction changes the account amount, the amount is read from the store again just before the amount is to be updated. If the amount has changed since the transaction began, the transaction fails itself; otherwise, the new amount is written to persistent storage.

The Components of a Distributed Transaction

A number of participants are in a distributed transaction. These include

  • Transaction manager This component is distributed across the transactional system. It manages and coordinates the work involved in the transaction. The transaction manager is exposed by the javax.transaction.TransactionManager interface in JTA.

  • Transaction context A transaction context identifies a particular transaction. In JTA the corresponding interface is javax.transaction.Transaction.

  • Transactional client A transactional client can invoke operations on one or more transactional objects in a single transaction. The transactional client that started the transaction is called the transaction originator. A transaction client is either an explicit or implicit user of JTA interfaces and has no interface representation in the JTA.

  • Transactional object A transactional object is an object whose behavior is affected by operations performed on it within a transactional context. A transactional object can also be a transactional client. Most Enterprise JavaBeans (EJB) are transactional objects.

  • Recoverable resource A recoverable resource is a transactional object whose state is saved to stable storage if the transaction is committed, and whose state can be reset to what it was at the beginning of the transaction if the transaction is rolled back. At commit time, the transaction manager uses the two-phase XA protocol when communicating with the recoverable resource to ensure transactional integrity when more than one recoverable resource is involved in the transaction being committed. Transactional databases and message brokers, such as JBossMQ, are examples of recoverable resources. A recoverable resource is represented using the javax.transaction.xa.XAResource interface in JTA.

The Two-phase XA Protocol

When a transaction is about to be committed, it is the responsibility of the transaction manager to ensure either all of it is committed or all of it is rolled back. If only a single recoverable resource is involved in the transaction, the task of the transaction manager is simple; it just has to tell the resource to commit the changes to stable storage.

When more than one recoverable resource is involved in the transaction, management of the commit gets more complicated. Simply asking each of the recoverable resources to commit changes to stable storage is not enough to maintain the atomic property of the transaction. If one recoverable resource has committed and another fails to commit, part of the transaction would be committed and the other part rolled back.

To get around this problem, the two-phase XA protocol is used. The two-phase XA protocol involves an extra prepare phase before the actual commit phase. Before asking any of the recoverable resources to commit the changes, the transaction manager asks all the recoverable resources to prepare to commit. When a recoverable resource indicates it is prepared to commit the transaction, it has ensured it can commit the transaction. The resource is still able to roll back the transaction if necessary.

So the first phase consists of the transaction manager asking all the recoverable resources to prepare to commit. If any of the recoverable resources fails to prepare, the transaction is rolled back. But if all recoverable resources indicate they were able to prepare to commit, the second phase of the XA protocol begins. This consists of the transaction manager asking all the recoverable resources to commit the transaction. Because all the recoverable resources have indicated they are prepared, this step cannot fail.

Heuristic Exceptions

In a distributed environment, communications' failures can happen. If communication between the transaction manager and a recoverable resource is not possible for an extended period of time, the recoverable resource might decide to unilaterally commit or roll back changes done in the context of a transaction. Such a decision is called a heuristic decision. It is one of the worst errors that can happen in a transaction system because it can lead to parts of the transaction being committed while other parts are rolled back, thus violating the atomicity property of the transaction and possibly leading to data integrity corruption.

Because of the dangers of heuristic exceptions, a recoverable resource that makes a heuristic decision is required to maintain all information about the decision in stable storage until the transaction manager tells it to forget about the heuristic decision. The actual data about the heuristic decision saved in stable storage depends on the type of recoverable resource and is not standardized. The idea is that a system manager can look at the data and possibly edit the resource to correct any data integrity problems.

Several different kinds of heuristic exceptions are defined by the JTA. The javax.transaction.HeuristicCommitException is thrown when a recoverable resource is asked to roll back to report that a heuristic decision was made and that all relevant updates have been committed. On the opposite end is the javax.transaction.HeuristicRollbackException, which is thrown by a recoverable resource when it is asked to commit to indicate that a heuristic decision was made and that all relevant updates have been rolled back.

The javax.transaction.HeuristicMixedException is the worst heuristic exception. It is thrown to indicate that parts of the transaction were committed and other parts were rolled back. The transaction manager throws this exception when some recoverable resources did a heuristic commit and other recoverable resources did a heuristic rollback.

Transaction Identities and Branches

In JTA, the identity of transactions is encapsulated in objects implementing the javax.transaction.xa.Xid interface. The transaction identity is an aggregate of three parts:

  • The format identifier indicates the transaction family and tells how the other two parts should be interpreted.

  • The global transaction ID denotes the global transaction within the transaction family.

  • The branch qualifier identifies a particular branch of the global transaction.

Transaction branches are used to identify different parts of the same global transaction. Whenever the transaction manager involves a new recoverable resource in a transaction, it creates a new transaction branch.



JBoss 4. 0(c) The Official Guide
JBoss 4.0 - The Official Guide
ISBN: B003D7JU58
EAN: N/A
Year: 2006
Pages: 137

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net