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:
- For transactions, a session bean can either use container-managed
transactions or implement bean-managed transactions; entity beans must
use container-managed transactions. To enable container-managed
transactions, you must set the transaction attribute to any value
except BeanManged and set the transaction isolation level
attribute. To enable bean-managed transactions, you must set the
transaction attribute to BeanManaged and set the transaction isolation level
attribute. For more information, see Setting transactional attributes in the deployment descriptor.
If you want a session bean to manage its own transactions, you must write
the code that explicitly demarcates the boundaries of a transaction as
described in Using bean-managed transactions.
If you want an EJB client to manage its own transactions, you must
explicitly code that client to do so as described in Managing transactions in an EJB client.
- For security, the run-as mode attribute is used by the EJB
server environments. For information on the valid values of this
attribute, see Setting the security attribute in the deployment descriptor.
These attributes, like the other deployment descriptor attributes, are set
by using one of the tools available. For more information, see Tools for developing and deploying enterprise beans.
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:
- The transaction attribute defines the transactional manner in
which the container invokes a method. This attribute is part of the
standard deployment descriptor. Setting the transaction attribute defines the valid values of this attribute and explains
their meanings.
- The transaction isolation level attribute defines the manner in
which transactions are isolated from each other by the container. This
attribute is an extension to the standard deployment descriptor. Setting the transaction isolation level attribute defines the valid values of this attribute and explains
their meanings.
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.
The following are valid values for this attribute in decreasing order of
transactional strictness:
- BeanManaged
- 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.
- 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 BeanManaged value or use the Required or RequiresNew
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.
- 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.
- RequiresNew
- 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.
- 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.
- NotSupported
- 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.
- Never
- Directs the container to invoke bean methods without a transaction
context.
- If the client invokes a bean method from within a transaction context, the
container throws the java.rmi.RemoteException exception.
- If the client invokes a bean method from outside a transaction context,
the container behaves in the same way as if the NotSupported transaction
attribute was set. The client must call the method without a
transaction context.
Table 1. Effect of the enterprise bean's transaction attribute on the transaction context
Transaction attribute
| Client transaction context
| Bean transaction context
|
Mandatory
| No transaction
| Not allowed
|
Client transaction
| Client transaction
|
RequiresNew
| No transaction
| New transaction
|
Client transaction
| New transaction
|
Required
| No transaction
| New transaction
|
Client transaction
| Client transaction
|
Supports
| No transaction
| No transaction
|
Client transaction
| Client transaction
|
NotSupported
| No transaction
| No transaction
|
Client transaction
| No transaction
|
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.
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:
- Serializable
- This level prohibits all of the following types of reads:
- Dirty reads, where a transaction reads a database row
containing uncommitted changes from a second transaction.
- Nonrepeatable reads, where one transaction reads a row, a
second transaction changes the same row, and the first transaction rereads the
row and gets a different value.
- Phantom reads, where one transaction reads all rows that
satisfy an SQL WHERE condition, a second transaction inserts a row that also
satisfies the WHERE condition, and the first transaction applies the same
WHERE condition and gets the row inserted by the second transaction.
- RepeatableRead
- This level prohibits dirty reads and nonrepeatable reads, but it allows
phantom reads.
- ReadCommitted
- This level prohibits dirty reads, but allows nonrepeatable reads and
phantom reads.
- ReadUncommitted
- 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:
- Session beans and entity beans with bean-managed persistence
(BMP)--For each database connection used by the bean, the container sets
the transaction isolation level at the start of each transaction.
- Entity beans with container-managed persistence (CMP)--The container
generates database access code that implements the specified isolation
level.
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 acceptable level of risk to data consistency
- The acceptable levels of concurrency and performance
- The isolation levels supported by the underlying database
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
Serializable value protects data by eliminating concurrent access to
it. Conversely, the ReadUncommitted 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 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 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
ReadUncommitted 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.
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.
- Identity of Caller
- The security service makes no changes to the principal's credential
properties.
- Identity of EJB Server
- The security service alters the principal's credential properties to
match the credential properties associated with the EJB server.
- Identity Assigned to Specified Role
- A security principal that has been assigned to the specified role is used
for the execution of the bean's methods. This association is part
of the application binding where the role is associated with a user ID and
password of a user who is granted that role.