Transaction is the execution of a unit-of-work. A unit-of-work is a set of activities that relate to each other and must be completed together.
Four (ACID) characteristics of a transaction are:
1. Atomic
Transaction must execute completely or not at all.
2. Consistent
Transaction must transition the data from one consistent state to another. Access should not be allowed to inconsistent (dirty) data.
3. Isolated
Transactions may run concurrently, but each transaction should run in isolation and should not be interfered by other transactions and processes.
4. Durable
After the transaction is complete, resultant data should be written to a physical storage.
Currently, EJB only supports Flat Transactions.
1. Flat Transaction
Simple Transaction model, where a transaction consists of a series of operations. If all the operations succeed, the transaction is committed. Even if one operation fails, transaction is rolled back.
2. Nested Transaction
Nested transaction is a tree of transactions. The ‘main’ transaction contains sub-transactions. Each sub-transaction can individually roll back. If all the sub-transactions succeed the nested transaction is committed.
1. Declarative Transaction Management (or Demarcation)
EJB allows for Declarative Transaction Management. Using Declarative Transaction Management, the transaction behavior of beans can be controlled using the deployment descriptor, which sets transaction attributes for individual bean methods.
2. Programmatic Transaction Management (or Demarcation)
Developers are required to write transaction code within the business logic. Programmatic Transaction Management involves the use of API’s like OTS (Object Transaction Service), JTS (Java Transaction service) and JTA (Java Transaction API).
Transaction attributes are set in the deployment descriptor. It is possible to set a transaction attribute to the whole bean or to individual methods. A transaction attribute must be specified for the methods id the remote interface of a session bean and for the methods in the home and remote interfaces of an entity bean. Transactional behavior of the bean can be changed easily, just by changing the transactional attribute in the deployment descriptor. It is recommended that components always access an EIS under the scope of a transaction since this provides some guarantee on the integrity and consistency of the data.
1. Not Supported
Bean does not support transactions. If the client is associated with a transaction, it is suspended. If the bean method is invoking an ERP system and that particular resource manager is not supported, it is best to suspend the client transaction. That is when NotSupported attribute is set.
2. Supports
Bean supports transaction but is not required. If the client is associated with a transaction, bean takes part in the transaction. If the client is not associated with a transaction, bean does not start a transaction. Not used generally.
3. Required
Bean will always be part of a transaction. If the client is associated with a transaction, bean takes part in the transaction. If the client is not associated with a transaction, bean starts a transaction. Default choice, so that, bean method is always associated with a transaction.
4. Requires New
Bean will always start a new transaction. If the client is associated with a transaction or not, bean always starts a new transaction. Used when the bean method needs to commit the results unconditionally, like logging user information. Even if the client’s transaction fails, logging is done.
5. Mandatory
The client must be associated with a transaction; otherwise, invocation will fail, throwing a TransactionRequiredException.
6. Never
The client must not be associated with a transaction; otherwise, invocation will fail, throwing a RemoteException
1. Dirty Read
When the application reads data that has not been committed.
2. Unrepeatable Read
Application reads some data, but upon rereading the data, the ‘existing’ data has been changed. This happens because some other application has updated the data after the first read.
3. Phantom Reads
Phantom is a ‘new’ set of data that appears in a database between two reads. This happens because some other application has inserted the data after the first read.
Going back to the ‘I’ in ACID characteristics of a Transaction. We understand that transactions have to be isolated. Isolation is achieved by locking rows and tables in the database. Therefore, Higher levels of isolation will degrade the performance and lower levels of isolation will corrupt the database. We have to strike a right balance.
1. Read Uncommitted
Lowest level of isolation. Experiences all the transactional problems of Dirty read, Unrepeatable read and Phantom read. If we know that there are no concurrent transactions this isolation level can be assigned to improve performance.
2. Read Committed
Application will only read committed data. Experiences transactional problems of Unrepeatable read and Phantom read. Suitable for applications that report data. As reporting tools are not mission-critical, taking a snapshot of data is sufficient. Default Isolation level for an EIS.
3. Repeatable Read
Uses transactional locks to lock all the rows read, solving the unrepeatable read problem. Experiences the transactional problem of Phantom read. Suitable for applications that read and update data.
4. Serializable
All the Transactional Problems are solved using Table locks. Perfect Transactional Isolation. Suitable for mission-critical systems. Use with care as the isolation comes at the cost of performance.
If components involved in a transaction are deployed on more than one server, the transaction is termed as Distributed transaction. Each server would have a transaction manger and the transaction would have a transaction coordinator.
Phase 1: The transaction coordinator sends a ‘before commit’ message to all transaction mangers involved in the transaction. If any transaction manager decides to abort, it will do so and the transaction is cancelled.
Phase 2: If none of the transaction managers has aborted, it means all is well and the transaction coordinator sends a ‘commit’ message and the transaction managers do the actual updates.
We use the javax.transaction.UserTransaction interface of the JTA for working with transactions.
In EJB 1.1, only session beans can be bean-managed transaction beans. In stateless session beans, the transaction must be started and completed in the same method.
Client application (Web component like JSP or Servlet) can obtain a UserTransaction using JNDI. Transaction should start and complete in the service method.
Code Example:
Context iCtx = new InitialContext();
UserTransaction uTran = (UserTranssaction) iCtx.lookup(“java:comp/UserTransaction”);
UTran.begin();
//Write code to do the unit-of-work
Utran.commit();
Session Beans can obtain a UserTransaction from SessionContext.
Code Example:
UserTransaction uTran = sessionContext. getUserTranssaction();
UTran.begin();
//Write code to do the unit-of-work
Utran.commit();
Only beans that manage their own transactions have access to UserTransaction from EJBContext. Beans that do not manage their transaction can only access setRollbackOnly() and getRollbackOnly() methods of EJBContext. An Enterprise bean can choose to roll back a transaction started by the container using the method setRollbackOnly on the SessionContext or EntityContext object.
Transaction can span multiple components and enterprise information systems (EIS). The transaction is propagated automatically between components and to EIS accessed by the components within that transaction.
1. System Exceptions
java.lang.RuntimeException, java.rmi.RemoteException and their subtypes. Remember, javax.ejb.EJBException is a subclass of RuntimeException.
2. Application Exceptions
Any exception that does not extend java.lang.RuntimeException (or) java.rmi.RemoteException.
Transactions are automatically rolled back if a system exception is thrown from a bean method. Transactions are not automatically rolled back if an application exception is thrown.