# EJBs and Transactions

This topic discusses how to set transaction parameters for session, entity, and message-driven beans. It includes the following sections:

- What are Transactions?
- Bean and Container Managed Transactions
- Transaction Attributes
- Transaction Isolation

##
What are Transactions?

A transaction is unit of work containing activities that need to be completed together. For instance, for an online travel site, you might have a session bean method bookTravel that takes a credit card, ensures its valid, charges the price of the ticket on the credit card, and books the ticket. This method invoke methods on other EBJs to help accomplish these steps. For instance, methods of Customer, CreditCard and AirlineTicket beans will be invoked during the execution of this method. If all these steps complete successfully, the transaction succeeds. If any of these steps fails, the entire transaction fails and any changes made by previous steps are rolled back. For instance, if the ticket price is charged on the credit card, but booking the ticket fails, the charge on the credit card must be undone.

If all activities that make up the transaction execute successfully, all changes that were made as part of the transaction are committed. If the transaction fails, these changes are rolled back.

Reliable transactions have the following properties:

- Atomic. For a transaction to succeed, all steps that are part of the same transaction must complete. If any of these steps fails, the transaction fails. For the bookTravel method this means that if one of the steps throws an exception, the entire transaction fails, meaning that any changes already made as part of this transaction must be rolled back.
- Consistent. The transaction must leave the system in a correct state. This means that for the bookTravel method all activities that make up a transaction of this kind must be included. For instance, booking a ticket but not charging the customer will cause an incorrect state. Consistency also includes database integrity. For instance, after the bookTravel method completes successfully, a customer and airline ticket record must exist with referential integrity between these records.
- Isolated. A transaction must execute as if there were no other transactions running concurrently. In other words, a transaction must run without being interfered by other transactions (or causing interference to other transactions). Transaction Isolation is discussed in more detail below.
- Durable. If a transaction commits, the data changes made must be stored such that they survive system failure, for instance by storing the data in a database. For the bookTravel method, customer and airline tickets are represented by entity beans and an entity relationship is defined between these beans.

### Runtime and Checked Exceptions

An EJB method can throw a runtime exception or a checked expection, that is, an exception that does not extend a RuntimeException and must be caught in a try-catch block. Runtime exceptions will cause the transaction to fail and changes to be rolled back. Checked exceptions do not cause transaction failure. For more information on runtime and checked exceptions, and how these should be handled by the client application, see Handling EJB Exceptions.

## Bean and Container Managed Transactions

Transactions by session and message-driven beans can be managed by the bean or by the EJB container. Using container-managed transactions, also known as declarative transaction management is strongly recommended. When using container-managed transactions, the EJB container handles the transaction following the transaction attributes set for individual EJB methods (more on this below). Bean-managed transactions, also known as explicit transaction management, require you to explicitly handle the transaction management in the code. To enable bean-managed transaction, you must set the transaction-type attribute of the ejbgen:session or ejbgen:message-driven annotation to Bean. For session beans, this attribute is located in the Deployment section of the Property Editor. The details of explicit transaction management are beyond the scope of this documentation. Transactions of entity beans (including BMP entity beans) are always container-managed.

## Transaction Attributes

When the bookTravel method is invoked by by a client application, a transaction starts. The methods of Customer, CreditCard and AirlineTicket beans that are invoked by the bookTravel method are in principle part of the same transaction. In other words, these beans are likely participating in the same transaction and are part of the transaction scope. Transaction attributes determine whether an EJB's method actually participates in the same transaction.

The following transaction attributes are defined for session and entity beans:

- NotSupported. This method does not support a transaction. If the method is called as part of a transaction, the method is not part of the transaction scope and the transaction is suspended until the method has been executed.
- Supports. If the method is called as part of a transaction, it becomes part of the transaction scope. If the method call is not part of a transaction, the method executes as is without changing the transaction specifics.
- Required. If the method is called as part of a transaction, it become part of the transaction scope. If the method call is not part of a transaction, the method is executed within its own transaction, propagating the transaction scope to all methods it in turn invokes.
- RequiresNew. The method always executes within its own transaction, propagating the transaction scope to all methods it in turn invokes. If the method is called as part of a transaction, this transaction is suspended while this method executes within its own transaction. If the latter transaction fails, it does not affect the suspended transaction.
- Mandatory. If the method is called as part of a transaction, it become part of the transaction scope. If the method call is not part of a transaction, it will throw a javax.transaction.TransactionRequiredException or javax.transaction.TransactionRequiredLocalException.
- Never. If the method is called as part of a transaction, it will throw a RemoteException (to remote clients) or a EJBException (to local clients). If the method call is not part of a transaction, the method executes as is without changing the transaction specifics.

Message-driven beans only allow the NotSupported and Required transaction attributes. When set to Required, the message-driven bean executes as part of its own transaction. In other words, if the transaction fails, changes that were made as part of the onMessage method are rolled back, but the occurrence of an exception has no direct effect on the EJB or client application sending the JMS message, as the sender and the message-driven bean are decoupled. For more information, see Processing JMS Messages.

You can set transaction attributes on the entire EJB or on individual methods of session and entity beans. To set the transaction attribute for all methods of the EJB, use the default-transaction attribute of the ejbgen:entity, ejbgen:session or ejbgen:message-driven annotation. For session and entity beans, this attribute is located in the General section of the Property Editor. To override the default transaction attribute for an individual method of a session or entity bean, set the transaction-attribute attribute for the method via the Property Editor or in the source code on the method's ejbgen tag (ejbgen:local-method, ejbgen:local-home-method, ejbgen:remote-method, or ejbgen:remote-home-method).

## Transaction Isolation

The transaction isolation level determines how isolated a transaction is from another. The various isolation levels are defined with respect to three isolation phenomena:

- Dirty Reads. A transaction reads data written by another transaction that has not been committed yet. Because this data is uncommitted, a transaction failure would roll back these read changes.

- Nonrepeatable Reads. A transaction rereads data it has previously read and finds that data has been modified by another committed transaction in the meantime.

- Phantom Reads. A transaction reexecutes a query returning a set of rows that satisfy a search condition and finds that the set of rows satisfying the condition has changed due to another committed transaction in the meantime.

The following transaction isolation levels are defined for session and entity beans:

- TransactionReadUncommitted. A transaction may read any data currently on a data page, regardless of whether or not the data has been committed. Dirty reads, nonrepeatable reads, and phantom reads are possible.
- TransactionReadCommitted. A transaction is not allowed to read uncommitted data. Dirty reads are not possible, but nonrepeatable reads and phantom reads are.
- TransactionRepeatableRead. Once a transaction has read a set of data, repeated reads of the same data return the same values, even if other transactions have subsequently modified the data. Dirty reads and nonrepeatable reads are not possible, but phantom reads are.
- TransactionSerializable. A transaction ensures that no other transaction can read or write to the data it accesses. Dirty reads, nonrepeatable reads and phantom reads are not possible.

You can set the transaction isolation level using the isolation-level attribute on the ejbgen:method-isolation-level-pattern, ejbgen:local-method, and ejbgen:remote-method tags. All the methods invoked within a transaction must have the same isolation level. You cannot mix isolation levels.

The transaction isolation level setting interacts with an entity bean's concurrency strategy as set with the ejbgen:entity concurrency-strategy attribute. Specifically, when the Optimistic or the Exclusive concurrency strategies are used, the transaction isolation level setting is ignored.

### Oracle Database

Even with an isolation-level setting of TransactionSerializable, Oracle does not detect serialization problems until commit time. The error message returned is:

    java.sql.SQLException: ORA-08177: can't serialize access for this transaction

WebLogic provides special isolation-level settings to prevent this:

- TransactionReadCommittedForUpdate. When set, every SELECT query from that point on will have ForUpdate added to acquired locks on the selected rows. Consequently, if Oracle cannot lock the rows affected by the query immediately, then it waits until the rows are free. This condition remains in effect until the transaction succeeds or fails.
- TransactionReadCommittedForUpdateNoWait. When set, every SELECT query from that point on will have ForUpdateNoWait added to acquire locks on the selected rows. Consequently, if Oracle cannot lock the rows affected by the query immediately, then Oracle terminates the query before completion. This condition remains in effect until the transaction succeeds or fails.

Related Topics

@ejbgen:session Annotation

@ejbgen:entity Annotation

@ejbgen:message-driven Annotation

@ejbgen:local-method Annotation

@ejbgen:local-home-method Annotation

@ejbgen:remote-method Annotation

@ejbgen:remote-home-method Annotation

@ejbgen:method-isolation-level-pattern Annotation