Enabling transactions and security in enterprise beans

This chapter examines how to enable transactions and security in enterprise beans by setting the appropriate deployment descriptor attributes:

These attributes, like the other deployment descriptor attributes, are set by using one of the tools available with either the EJB server (AE) or the EJB server (CB). For more information, see Tools for developing and deploying enterprise beans in the EJB server (AE) environment or Tools for developing and deploying enterprise beans in the EJB server (CB) environment.


Setting transactional attributes in the deployment descriptor

The EJB Specification describes the creation of applications that enforce transactional consistency on the data manipulated by the enterprise beans. However, unlike other specifications that support distributed transactions, the EJB specification does not require enterprise bean and EJB client developers to write any special code to use transactions. Instead, the container manages transactions based on two deployment descriptor attributes associated with the EJB module, and the enterprise bean and EJB application developers are freed to deal with the business logic of their applications.

Enterprise bean developers can specifically design enterprise beans and EJB applications that explicitly manage transactions. For more information, see Using bean-managed transactions.

Under most conditions, transaction management can be handled within the enterprise beans, freeing the EJB client developer of this task. However, EJB clients can participate in transactions if required or desired. For more information, see Managing transactions in an EJB client.

Two attributes determine the way in which an enterprise bean is managed from a transactional perspective:

Setting the transaction attribute
The transaction attribute defines the transactional manner in which the container invokes enterprise bean methods. This attribute is set for individual methods in a bean.
Note:
The EJB server (CB) does not support the setting of the transaction attribute for individual enterprise bean methods; the transaction attribute can be set only for the entire bean.
The following are valid values for this attribute in decreasing order of transactional strictness:

TX_BEAN_MANAGED
Notifies the container that the bean class directly handles transaction demarcation. This attribute value can be specified only for session beans and it cannot be specified for individual bean methods. For more information on designing session beans to implement this attribute value, see Using bean-managed transactions.

In the EJB server (CB) environment, if a stateful session bean has this attribute value, a method that begins a transaction must also complete that transaction (commit or roll back the transaction). In other words, a transaction cannot span multiple methods in a stateful session bean when used in the EJB server (CB) environment.

TX_MANDATORY
Directs the container to always invoke the bean method within the transaction context associated with the client. If the client attempts to invoke the bean method without a transaction context, the container throws the javax.jts.TransactionRequiredException exception to the client. The transaction context is passed to any EJB object or resource accessed by an enterprise bean method.

EJB clients that access these entity beans must do so within an existing transaction. For other enterprise beans, the enterprise bean or bean method must implement the TX_BEAN_MANAGED value or use the TX_REQUIRED or TX_REQUIRES_NEW value. For non-enterprise bean EJB clients, the client must invoke a transaction by using the javax.transaction.UserTransaction interface, as described in Managing transactions in an EJB client.

In the EJB server (CB) environment, this attribute value must be used in entity beans with container-managed persistence (CMP) that use Host On-Demand (HOD) or the External Call Interface (ECI) to access CICS or IMS applications.

TX_REQUIRED
Directs the container to invoke the bean method within a transaction context. If a client invokes a bean method from within a transaction context, the container invokes the bean method within the client transaction context. If a client invokes a bean method outside of a transaction context, the container creates a new transaction context and invokes the bean method from within that context. The transaction context is passed to any enterprise bean objects or resources that are used by this bean method.

TX_REQUIRES_NEW
Directs the container to always invoke the bean method within a new transaction context, regardless of whether the client invokes the method within or outside of a transaction context. The transaction context is passed to any enterprise bean objects or resources that are used by this bean method.

The EJB server (CB) does not support this attribute value for enterprise beans written to version 1.0 of the EJB specification. It interprets the TX_REQUIRES_NEW attribute as TX_REQUIRED for Enterprise beans written to version 1.1 of the EJB specification.

TX_SUPPORTS
Directs the container to invoke the bean method within a transaction context if the client invokes the bean method within a transaction. If the client invokes the bean method without a transaction context, the container invokes the bean method without a transaction context. The transaction context is passed to any enterprise bean objects or resources that are used by this bean method.

In the EJB server (CB) environment, entity beans with CMP must be accessed within a transaction. If an entity bean with CMP uses this transaction attribute, the EJB client must initiate a transaction before invoking a method on the entity bean.

TX_NOT_SUPPORTED
Directs the container to invoke bean methods without a transaction context. If a client invokes a bean method from within a transaction context, the container suspends the association between the transaction and the current thread before invoking the method on the enterprise bean instance. The container then resumes the suspended association when the method invocation returns. The suspended transaction context is not passed to any enterprise bean objects or resources that are used by this bean method.

In the EJB server (CB) environment, entity beans with CMP must be accessed within a transaction. Therefore, this attribute value is not supported in entity beans with CMP in the EJB server (CB) environment.

TX_NEVER
Directs the container to invoke bean methods without a transaction context.

In the EJB server (CB) environment, the TX_NEVER attribute is interpreted as TX_NOT_SUPPORTED. Therefore, no exception is thrown if the client invokes a bean method from within a transaction context.


Table 3. Effect of the enterprise bean's transaction attribute on the transaction context

Transaction attribute Client transaction context Bean transaction context
TX_MANDATORY No transaction Not allowed
Client transaction Client transaction
TX_REQUIRES_NEW No transaction New transaction
Client transaction New transaction
TX_REQUIRED No transaction New transaction
Client transaction Client transaction
TX_SUPPORTS No transaction No transaction
Client transaction Client transaction
TX_NOT_SUPPORTED No transaction No transaction
Client transaction No transaction
TX_NEVER No transaction No transaction
No transaction No transaction

When setting the deployment descriptor for an entity bean, you can mark getter methods as "Read-Only" methods to improve performance. If a transaction unit of work includes no methods other than "Read-Only" designated methods, then the entity bean state synchronization does not invoke store.

Setting the transaction isolation level attribute
Note:
The EJB server (CB) does not support the transaction isolation level attribute.
The transaction isolation level determines how strongly one transaction is isolated from another. This attribute is set for individual methods in a bean. However, within a transactional context, the isolation level associated with the first method invocation becomes the required isolation level for all other methods invoked within that transaction. If a method is invoked with a different isolation level from that of the first method, the java.rmi.RemoteException exception is thrown.

The following are valid values for this attribute, in decreasing order of isolation:

TRANSACTION_SERIALIZABLE
This level prohibits all of the following types of reads:

TRANSACTION_REPEATABLE_READ
This level prohibits dirty reads and nonrepeatable reads, but it allows phantom reads.

TRANSACTION_READ_COMMITTED
This level prohibits dirty reads, but allows nonrepeatable reads and phantom reads.

TRANSACTION_READ_UNCOMMITTED
This level allows dirty reads, nonrepeatable reads, and phantom reads.

These isolation levels correspond to the isolation levels defined in the Java Database Connectivity (JDBC) java.sql.Connection interface.

The container uses the transaction isolation level attribute as follows:

None of these values permits two transactions to update the same data concurrently; one transaction must end before another can update the same data. These values determine only how locks are managed for reading data. However, risks to consistency can arise from read operations when a transaction does further work based on the values read. For example, if one transaction is updating a piece of data and a second transaction is permitted to read that data after it has been changed but before the updating transaction ends, the reading transaction can make a decision based on a change that is eventually rolled back. The second transaction risks making a decision on transient data.

Deciding which isolation level to use depends on several factors:

The first two factors, risk to consistency and level of concurrency, are related. Decreasing the risk to consistency requires you to decrease concurrency because reducing the risk to consistency requires holding locks longer. The longer a lock is held on a piece of data, the longer concurrently running transactions must wait to access that data. The TRANSACTION_SERIALIZABLE value protects data by eliminating concurrent access to it. Conversely, the TRANSACTION_READ_UNCOMMITTED value allows the highest degree of concurrency but entails the greatest risk to consistency. You need to balance these two factors appropriately for your application.

By default, most developers deploy enterprise beans with the transaction isolation level set to TRANSACTION_SERIALIZABLE. This is the default value in IBM VisualAge for Java Enterprise Edition and other deployment tools. It is also the most restrictive and protected transaction isolation level incurring the most overhead. Some workloads do not require the isolation level and protection afforded by TRANSACTION_SERIALIZABLE. A given application might never update the underlying data or be run with other applications that also make concurrent updates. In that case, the application would not have to be concerned with dirty, non-repeatable, or phantom reads. The TRANSACTION_READ_UNCOMMITTED isolation level would probably be sufficient.

Because the transaction isolation level is set in the EJB module's deployment descriptor, the same enterprise bean could be reused in different applications with different transaction isolation levels. The isolation level requirements should be reviewed and adjusted appropriately to increase performance.

The third factor, isolation levels supported in the database, means that although the EJB specification allows you to request one of the four levels of transaction isolation, it is possible that the database being used in the application does not support all of the levels. Also, vendors of database products implement isolation levels differently, so the precise behavior of an application can vary from database to database. You need to consider the database and the isolation levels it supports when deciding on the value for the transaction isolation attribute in deployment descriptors. Consult your database documentation for more information on supported isolation levels.


Setting the security attribute in the deployment descriptor

When an EJB client invokes a method on an enterprise bean, the user context of the client principal is encapsulated in a CORBA Current object, which contains credential properties for the principal. The Current object is passed among the participants in the method invocation as required to complete the method.

The security service uses the credential information to determine the permissions that a principal has on various resources. At appropriate points, the security service determines if the principal is authorized to use a particular resource based on the principal's permissions.

If the method invocation is authorized, the security service does the following with the principal's credential properties based on the value of the run-as mode attribute of the enterprise bean. If a specific identity is required, the RunAsIdentity attribute is used to specify that identity.

CLIENT_IDENTITY
The security service makes no changes to the principal's credential properties.

SYSTEM_IDENTITY
The security service alters the principal's credential properties to match the credential properties associated with the EJB server.

SPECIFIED_IDENTITY
The security service attempts to match the principal's credential properties with the identity of any application with which the enterprise bean is associated. If successful, the security service alters the principal's credential properties to match the credential properties of the application.