Sun Java System Application Server Enterprise Edition 8.1 2005Q2 Developer's Guide

- Previous: Chapter 5 Developing Web Applications
- Next: Chapter 7 Using Container-Managed Persistence for Entity Beans

# Chapter 6 Using Enterprise JavaBeans Technology

This chapter describes how Enterprise JavaBeansTM (EJBTM) technology is supported in the Sun Java System Application Server. This chapter addresses the following topics:

- Summary of EJB 2.1 Changes

- Value Added Features

- EJB Timer Service

- Using Session Beans

- Using Read-Only Beans

- Using Message-Driven Beans

- Handling Transactions with Enterprise Beans

# Summary of EJB 2.1 Changes

The Application Server supports the Sun Microsystems Enterprise JavaBeans (EJB) architecture as defined by the Enterprise JavaBeans Specification, v2.1 and is compliant with the Enterprise JavaBeans Specification, v2.0.

Note –

The Application Server is backward compatible with 1.1 and 2.0 enterprise beans. However, to take advantage of version 2.1 features, you should develop new beans as 2.1 enterprise beans.

The changes in the Enterprise JavaBeans Specification, v2.1 that impact enterprise beans in the Application Server environment are as follows:

- EJB Timer Service: This is a container-managed, reliable, and transactional notification service that provides methods to allow callbacks to be scheduled for time-based events. See EJB Timer Service.

- Message-driven beans: This type of enterprise bean can consume any inbound messages from a Connector 1.5 inbound resource adapter, primarily but not exclusively JMS messages. See Using Message-Driven Beans.

- EJB Web Services: A stateless session bean can serve as a web service endpoint. In addition, all EJB component types can act as web service clients. For details, see the web service elements in the `sun-ejb-jar.xml` file, described in The sun-ejb-jar.xml File.

# Value Added Features

The Application Server provides a number of value additions that relate to EJB development. These capabilities are discussed in the following sections (references to more in-depth material are included):

- Read-Only Beans

- pass-by-reference

- Pooling and Caching

- Bean-Level Container-Managed Transaction Timeouts

- Priority Based Scheduling of Remote Bean Invocations

- Immediate Flushing

## Read-Only Beans

Another feature that the Application Server provides is the read-only bean, an entity bean that is never modified by an EJB client. Read-only beans avoid database updates completely. A read-only bean is not portable.

A read-only bean can be used to cache a database entry that is frequently accessed but rarely updated (externally by other beans). When the data that is cached by a read-only bean is updated by another bean, the read-only bean can be notified to refresh its cached data.

The Application Server provides a number of ways by which a read-only bean’s state can be refreshed. By setting the `refresh-period-in-seconds` element in the `sun-ejb-jar.xml` file and the `trans-attribute` element in the `ejb-jar.xml` file, it is easy to configure a read-only bean that is (a) always refreshed, (b) periodically refreshed, (c) never refreshed, or (d) programmatically refreshed.

Read-only beans are best suited for situations where the underlying data never changes, or changes infrequently. For further information and usage guidelines, see Using Read-Only Beans.

## pass-by-reference

The `pass-by-reference` element in the `sun-ejb-jar.xml` file allows you to specify the parameter passing semantics for colocated remote EJB invocations. This is an opportunity to improve performance. However, use of this feature results in non-portable applications. See pass-by-reference.

## Pooling and Caching

The EJB container of the Application Server pools anonymous instances (message-driven beans, stateless session beans, and entity beans) to reduce the overhead of creating and destroying objects. The EJB container maintains the free pool for each bean that is deployed. Bean instances in the free pool have no identity (that is, no primary key associated) and are used to serve the method calls of the home interface. The free beans are also used to serve all methods for stateless session beans.

Bean instances in the free pool transition from a Pooled state to a Cached state after `ejbCreate` and the business methods run. The size and behavior of each pool is controlled using pool-related properties in the EJB container or the `sun-ejb-jar.xml` file.

In addition, the Application Server supports a number of tunable parameters that can control the number of “stateful” instances (stateful session beans and entity beans) cached as well as the duration they are cached. Multiple bean instances that refer to the same database row in a table can be cached. The EJB container maintains a cache for each bean that is deployed.

To achieve scalability, the container selectively evicts some bean instances from the cache, usually when cache overflows. These evicted bean instances return to the free bean pool. The size and behavior of each cache can be controlled using the cache-related properties in the EJB container or the `sun-ejb-jar.xml` file.

Pooling and caching parameters for the `sun-ejb-jar.xml` file are described in bean-cache.

### Pooling Parameters

One of the most important parameters of Application Server pooling is `steady-pool-size`. When `steady-pool-size` is set to greater than 0, the container not only pre-populates the bean pool with the specified number of beans, but also attempts to ensure that there is always this many beans in the free pool. This ensures that there are enough beans in the ready to serve state to process user requests.

This parameter does not necessarily guarantee that no more than `steady-pool-size` instances exist at a given time. It only governs the number of instances that are pooled over a long period of time. For example, suppose an idle stateless session container has a fully-populated pool with a `steady-pool-size` of `10`. If 20 concurrent requests arrive for the EJB component, the container creates 10 additional instances to satisfy the burst of requests. The advantage of this is that it prevents the container from blocking any of the incoming requests. However, if the activity dies down to 10 or fewer concurrent requests, the additional 10 instances are discarded.

Another parameter, `pool-idle-timeout-in-seconds`, allows the administrator to specify, through the amount of time a bean instance can be idle in the pool. When `pool-idle-timeout-in-seconds` is set to greater than 0, the container removes or destroys any bean instance that is idle for this specified duration.

### Caching Parameters

Application Server provides a way that completely avoids caching of entity beans, using commit option C. Commit option C is particularly useful if beans are accessed in large number but very rarely reused. For additional information, refer to Commit Options.

The Application Server caches can be either bounded or unbounded. Bounded caches have limits on the number of beans that they can hold beyond which beans are passivated. For stateful session beans, there are three ways (LRU, NRU and FIFO) of picking victim beans when cache overflow occurs. Caches can also passivate beans that are idle (not accessed for a specified duration).

## Bean-Level Container-Managed Transaction Timeouts

The default transaction timeout for the domain is specified using the Transaction Timeout setting of the Transaction Service. A transaction started by the container must commit (or rollback) within this time, regardless of whether the transaction is suspended (and resumed), or the transaction is marked for rollback.

To override this timeout for an individual bean, use the optional `cmt-timeout-in-seconds` element in `sun-ejb-jar.xml`. The default value, `0`, specifies that the default Transaction Service timeout is used. The value of `cmt-timeout-in-seconds` is used for all methods in the bean that start a new container-managed transaction. This value is not used if the bean joins a client transaction.

## Priority Based Scheduling of Remote Bean Invocations

You can create multiple thread pools, each having its own work queues. An optional element in the `sun-ejb-jar.xml` file, `use-thread-pool-id`, specifies the thread pool that processes the requests for the bean. The bean must have a remote interface, or `use-thread-pool-id` is ignored. You can create different thread pools and specify the appropriate thread pool ID for a bean that requires a quick response time. If there is no such thread pool configured or if the element is absent, the default thread pool is used.

## Immediate Flushing

Normally, all entity bean updates within a transaction are batched and executed at the end of the transaction. The only exception is the database flush that precedes execution of a finder or select query.

Since a transaction often spans many method calls, you might want to find out if the updates made by a method succeeded or failed immediately after method execution. To force a flush at the end of a method’s execution, use the flush-at-end-of-method element in the `sun-ejb-jar.xml` file. Only non-finder methods in the Local, Local Home, Remote, and Remote Home interfaces of an entity bean can be flush-enabled.

Upon completion of the method, the EJB container updates the database. Any exception thrown by the underlying data store is wrapped as follows:

- If the method that triggered the flush is a `create` method, the exception is wrapped with `CreateException`.

- If the method that triggered the flush is a `remove` method, the exception is wrapped with `RemoveException`.

- For all other methods, the exception is wrapped with `EJBException`.

All normal end-of-transaction database synchronization steps occur regardless of whether the database has been flushed during the transaction.

# EJB Timer Service

The EJB Timer Service uses a database to store persistent information about EJB timers. The EJB Timer Service configuration can store persistent timer information in any database supported by the Application Server CMP container.

For a list of the JDBC drivers currently supported by the Application Server, see the Sun Java System Application Server Enterprise Edition 8.1 2005Q2 Release Notes. For configurations of supported and other drivers, see Configurations for Specific JDBC Drivers.

To change the database used by the EJB Timer Service, set the EJB Timer Service’s Timer DataSource setting to a valid JDBC resource. You must also create the timer database table. DDL files are located in install-dir`/lib/install/databases`. Ideally, each cluster should have its own timer table.

Using the EJB Timer Service is equivalent to interacting with a single JDBC resource manager. If an EJB component or application accesses a database either directly through JDBC or indirectly (for example, through an entity bean’s persistence mechanism), and also interacts with the EJB Timer Service, its data source must be configured with an XA JDBC driver.

You can change the following EJB Timer Service settings. You must restart the server for the changes to take effect.

- Minimum Delivery Interval - Specifies the minimum time in milliseconds before an expiration for a particular timer can occur. This guards against extremely small timer increments that can overload the server. The default is `7000`.

- Maximum Redeliveries - Specifies the maximum number of times the EJB timer service attempts to redeliver a timer expiration due for exception or rollback. The default is 1.

- Redelivery Interval - Specifies how long in milliseconds the EJB timer service waits after a failed `ejbTimeout` delivery before attempting a redelivery. The default is `5000`.

- Timer DataSource - Specifies the database used by the EJB Timer Service.

For information about configuring EJB Timer Service settings, see the Sun Java System Application Server Enterprise Edition 8.1 2005Q2 Administration Guide. For information about the `asadmin list-timers` and `asadmin migrate-timers` commands, see the Sun Java System Application Server Enterprise Edition 8.1 2005Q2 Reference Manual.

# Using Session Beans

This section provides guidelines for creating session beans in the Application Server environment. This section addresses the following topics:

- About the Session Bean Containers

- Stateful Session Bean Failover

- Restrictions and Optimizations

Extensive information on session beans is contained in the chapters 6, 7, and 8 of the Enterprise JavaBeans Specification, v2.1.

## About the Session Bean Containers

Like an entity bean, a session bean can access a database through JavaTM Database Connectivity (JDBCTM) calls. A session bean can also provide transaction settings. These transaction settings and JDBC calls are referenced by the session bean’s container, allowing it to participate in transactions managed by the container.

A container managing stateless session beans has a different charter from a container managing stateful session beans.

### Stateless Container

The stateless container manages stateless session beans, which, by definition, do not carry client-specific states. All session beans (of a particular type) are considered equal.

A stateless session bean container uses a bean pool to service requests. The Application Server specific deployment descriptor file, `sun-ejb-jar.xml`, contains the properties that define the pool:

- `steady-pool-size`

- `resize-quantity`

- `max-pool-size`

- `pool-idle-timeout-in-seconds`

For more information about `sun-ejb-jar.xml`, see The sun-ejb-jar.xml File.

The Application Server provides the `wscompile` and `wsdeploy` tools to help you implement a web service endpoint as a stateless session bean. For more information about these tools, see the Sun Java System Application Server Enterprise Edition 8.1 2005Q2 Reference Manual.

### Stateful Container

The stateful container manages the stateful session beans, which, by definition, carry the client-specific state. There is a one-to-one relationship between the client and the stateful session beans. At creation, each stateful session bean (SFSB) is given a unique session ID that is used to access the session bean so that an instance of a stateful session bean is accessed by a single client only.

Stateful session beans are managed using cache. The size and behavior of stateful session beans cache are controlled by specifying the following `sun-ejb-jar.xml` parameters:

- `max-cache-size`

- `resize-quantity`

- `cache-idle-timeout-in-seconds`

- `removal-timeout-in-seconds`

- `victim-selection-policy`

The `max-cache-size` element specifies the maximum number of session beans that are held in cache. If the cache overflows (when the number of beans exceeds `max-cache-size`), the container then passivates some beans or writes out the serialized state of the bean into a file. The directory in which the file is created is obtained from the EJB container using the configuration APIs.

For more information about `sun-ejb-jar.xml`, see The sun-ejb-jar.xml File.

The passivated beans are stored on the file system. The Session Store Location setting in the EJB container allows the administrator to specify the directory where passivated beans are stored. By default, passivated stateful session beans are stored in application-specific subdirectories created under domain-dir`/session-store`.

Note –

Make sure the `delete` option is set in the `server.policy` file, or expired file-based sessions might not be deleted properly. For more information about `server.policy`, see The server.policy File.

The Session Store Location setting also determines where the session state is persisted if it is not highly available; see Choosing a Persistence Store.

## Stateful Session Bean Failover

An SFSB’s state can be saved in a persistent store in case a server instance fails. The state of an SFSB is saved to the persistent store at predefined points in its life cycle. This is called checkpointing. If SFSB checkpointing is enabled, checkpointing generally occurs after any transaction involving the SFSB is completed, even if the transaction rolls back.

However, if an SFSB participates in a bean-managed transaction, the transaction might be committed in the middle of the execution of a bean method. Since the bean’s state might be undergoing transition as a result of the method invocation, this is not an appropriate instant to checkpoint the bean’s state. In this case, the EJB container checkpoints the bean’s state at the end of the corresponding method, provided the bean is not in the scope of another transaction when that method ends. If a bean-managed transaction spans across multiple methods, checkpointing is delayed until there is no active transaction at the end of a subsequent method.

The state of an SFSB is not necessarily transactional and might be significantly modified as a result of non-transactional business methods. If this is the case for an SFSB, you can specify a list of checkpointed methods. If SFSB checkpointing is enabled, checkpointing occurs after any checkpointed methods are completed.

The following sample application demonstrates SFSB session persistence:

    install-dir/samples/ee-samples/failover/apps/sfsbfailover

The following table lists the types of references that SFSB failover supports. All objects bound into an SFSB must be one of the supported types. In the table, No indicates that failover for the object type might not work in all cases and that no failover support is provided. However, failover might work in some cases for that object type. For example, failover might work because the class implementing that type is serializable.

Table 6–1 Object Types Supported for J2EE Stateful Session Bean State Failover

Java Object Type | Failover Support
--- | ---
Stateless session, stateful session, and entity bean local home reference, local object reference | Yes
Colocated and distributed stateless session, stateful session, and entity bean remote home reference, remote reference | Yes
JNDI Context | Yes, `InitialContext` and `java:comp/env`
UserTransaction | Yes, but if the instance that fails is never restarted, any prepared global transactions are lost and might not be correctly rolled back or committed
JDBC DataSource | No
Java Message Service (JMS) ConnectionFactory, Destination | No
JavaMailTM Session | No
Connection Factory | No
Administered Object | No
Web service reference | No
Serializable Java types | Yes

For more information about the `InitialContext`, see Accessing the Naming Context. For more information about transaction recovery, see Chapter 12, Using the Transaction Service. For more information about Administered Objects, see Creating Physical Destinations.

Note –

Idempotent URLs are supported along the HTTP path, but not the RMI-IIOP path. For more information, see Configuring Idempotent URL Requests and the Sun Java System Application Server Enterprise Edition 8.1 2005Q2 Administration Guide.

If a server instance to which an RMI-IIOP client request is sent crashes during the request processing (before the response is prepared and sent back to the client), an error is sent to the client. The client must retry the request explicitly. When the client retries the request, the request is sent to another server instance in the cluster, which retrieves session state information for this client.

HTTP sessions can also be saved in a persistent store in case a server instance fails. In addition, if a distributable web application references an SFSB, and the web application’s session fails over, the EJB reference is also failed over. For more information, see Distributed Sessions and Persistence.

If an SFSB that uses session persistence is undeployed while the Application Server instance is stopped, the session data in the persistence store might not be cleared. To prevent this, undeploy the SFSB while the Application Server instance is running.

Configure SFSB failover by:

- Choosing a Persistence Store

- Enabling Checkpointing

- Specifying Methods to Be Checkpointed (optional)

### Choosing a Persistence Store

Two types of persistent storage are supported for passivation and checkpointing of the SFSB state:

- The local file system - Allows a single server instance to recover the SFSB state after a failure and restart. This store also provides passivation and activation of the state to help control the amount of memory used. This option is not supported in a production environment that requires SFSB state persistence. This is the default storage mechanism.

- The high-availability database (HADB) - Allows a cluster of server instances to recover the SFSB state if any server instance fails. The HADB is also used as the passivation and activation store. Use this option in a production environment that requires SFSB state persistence. For information about how to set up and configure this database, see the description of the `configure-ha-cluster` command in the Sun Java System Application Server Enterprise Edition 8.1 2005Q2 Reference Manual.

Choose the persistence store in one of the following ways:

- To use the local file system, first disable availability. Select the Availability Service component under the relevant configuration in the Administration Console. Uncheck the Instance Level Availability box. Then select the EJB Container component and edit the Session Store Location value. The default is domain-dir`/session-store`.

- To use the HADB, select the Availability Service component under the relevant configuration in the Administration Console. Check the Instance Level Availability box. To enable availability for the EJB container, select the EJB Container Availability tab, then check the Availability Service box.

For more information, see the Sun Java System Application Server Enterprise Edition 8.1 2005Q2 High Availability Administration Guide.

### Enabling Checkpointing

The following sections describe how to enable SFSB checkpointing:

- Server Instance and EJB Container Levels

- Application and EJB Module Levels

- SFSB Level

#### Server Instance and EJB Container Levels

To enable SFSB checkpointing at the server instance or EJB container level, see Choosing a Persistence Store.

#### Application and EJB Module Levels

To enable SFSB checkpointing at the application or EJB module level during deployment, use the `asadmin deploy` or `asadmin deploydir` command with the `--availabilityenabled` option set to `true`. For details, see the Sun Java System Application Server Enterprise Edition 8.1 2005Q2 Reference Manual.

#### SFSB Level

To enable SFSB checkpointing at the SFSB level, set `availability-enabled="true"` in the `ejb` element of the SFSB’s `sun-ejb-jar.xml` file as follows:

    <sun-ejb-jar>
       ...
       <enterprise-beans>
          ...
          <ejb availability-enabled="true">
             <ejb-name>MySFSB</ejb-name>
          </ejb>
       ...
       </enterprise-beans>
    </sun-ejb-jar>

### Specifying Methods to Be Checkpointed

If SFSB checkpointing is enabled, checkpointing generally occurs after any transaction involving the SFSB is completed, even if the transaction rolls back.

To specify additional optional checkpointing of SFSBs at the end of non-transactional business methods that cause important modifications to the bean’s state, use the checkpoint-at-end-of-method element within the `ejb` element in `sun-ejb-jar.xml`.

For example:

    <sun-ejb-jar>
       ...
       <enterprise-beans>
          ...
          <ejb availability-enabled="true">
             <ejb-name>ShoppingCartEJB</ejb-name>
             <checkpoint-at-end-of-method>
                <method>
                   <method-name>addToCart</method-name>
                </method>
             </checkpoint-at-end-of-method>
          </ejb>
          ...
       </enterprise-beans>
    </sun-ejb-jar>

The non-transactional methods in the `checkpoint-at-end-of-method` element can be:

- `create()` methods defined in the home interface of the SFSB, if you want to checkpoint the initial state of the SFSB immediately after creation

- For SFSBs using container managed transactions only, methods in the remote interface of the bean marked with the transaction attribute TX_NOT_SUPPORTED or TX_NEVER

- For SFSBs using bean managed transactions only, methods in which a bean managed transaction is neither started nor committed

Any other methods mentioned in this list are ignored. At the end of invocation of each of these methods, the EJB container saves the state of the SFSB to persistent store.

Note –

If an SFSB does not participate in any transaction, and if none of its methods are explicitly specified in the `checkpoint-at-end-of-method` element, the bean’s state is not checkpointed at all even if `availability-enabled="true"` for this bean.

For better performance, specify a small subset of methods. The methods chosen should accomplish a significant amount of work in the context of the J2EE application or should result in some important modification to the bean’s state.

## Restrictions and Optimizations

This section discusses restrictions on developing session beans and provides some optimization guidelines:

- Optimizing Session Bean Performance

- Restricting Transactions

### Optimizing Session Bean Performance

For stateful session beans, colocating the stateful beans with their clients so that the client and bean are executing in the same process address space improves performance.

### Restricting Transactions

The following restrictions on transactions are enforced by the container and must be observed as session beans are developed:

- A session bean can participate in, at most, a single transaction at a time.

- If a session bean is participating in a transaction, a client cannot invoke a method on the bean such that the `trans-attribute` element in the `ejb-jar.xml` file would cause the container to execute the method in a different or unspecified transaction context or an exception is thrown.

- If a session bean instance is participating in a transaction, a client cannot invoke the `remove` method on the session object’s home or component interface object or an exception is thrown.

# Using Read-Only Beans

A read-only bean is an entity bean that is never modified by an EJB client. The data that a read-only bean represents can be updated externally by other enterprise beans, or by other means, such as direct database updates.

Note –

Read-only beans are specific to Application Server and are not part of the Enterprise JavaBeans Specification, v2.1. Use of this feature results in a non-portable application.

Read-only beans are best suited for situations where the underlying data never changes, or changes infrequently. The following topics are addressed in this section:

- Read-Only Bean Characteristics and Life Cycle

- Read-Only Bean Good Practices

- Refreshing Read-Only Beans

- Deploying Read Only Beans

## Read-Only Bean Characteristics and Life Cycle

Read-only beans are best suited for situations where the underlying data never changes, or changes infrequently. For example, a read-only bean can be used to represent a stock quote for a particular company, which is updated externally. In such a case, using a regular entity bean might incur the burden of calling `ejbStore`, which can be avoided by using a read-only bean.

Read-only beans have the following characteristics:

- Only entity beans can be read-only beans.

- Either bean-managed persistence (BMP) or container-managed persistence (CMP) is allowed. If CMP is used, do not create the database schema during deployment. Instead, work with your database administrator to populate the data into the tables. See Chapter 7, Using Container-Managed Persistence for Entity Beans.

- Only container-managed transactions are allowed; read-only beans cannot start their own transactions.

- Read-only beans don’t update any bean state.

- `ejbStore` is never called by the container.

- `ejbLoad` is called only when a transactional method is called or when the bean is initially created (in the cache), or at regular intervals controlled by the bean’s `refresh-period-in-seconds` element in the `sun-ejb-jar.xml` file.

- The home interface can have any number of find methods. The return type of the find methods must be the primary key for the same bean type (or a collection of primary keys).

- If the data that the bean represents can change, then `refresh-period-in-seconds` must be set to refresh the beans at regular intervals. `ejbLoad` is called at this regular interval.

A read-only bean comes into existence using the appropriate find methods.

Read-only beans are cached and have the same cache properties as entity beans. When a read-only bean is selected as a victim to make room in the cache, `ejbPassivate` is called and the bean is returned to the free pool. When in the free pool, the bean has no identity and is used only to serve any finder requests.

Read-only beans are bound to the naming service like regular read-write entity beans, and clients can look up read-only beans the same way read-write entity beans are looked up.

## Read-Only Bean Good Practices

For best results, follow these guidelines when developing read-only beans:

- Avoid having any `create` or `remove` methods in the home interface.

- Use any of the valid EJB 2.1 transaction attributes for the `trans-attribute` element.

  The reason for having `TX_SUPPORTED` is to allow reading uncommitted data in the same transaction. Also, the transaction attributes can be used to force `ejbLoad`.

## Refreshing Read-Only Beans

There are several ways of refreshing read-only beans as addressed in the following sections:

- Invoking a Transactional Method

- Refreshing Periodically

- Refreshing Programmatically

### Invoking a Transactional Method

Invoking any transactional method invokes `ejbLoad`.

### Refreshing Periodically

Use the `refresh-period-in-seconds` element in the `sun-ejb-jar.xml` file to refresh a read-only bean periodically.

- If the value specified in `refresh-period-in-seconds` is zero or not specified, which is the default, the bean is never refreshed (unless a transactional method is accessed).

- If the value is greater than zero, the bean is refreshed at the rate specified.

Note –

This is the only way to refresh the bean state if the data can be modified external to the Application Server.

### Refreshing Programmatically

Typically, beans that update any data that is cached by read-only beans need to notify the read-only beans to refresh their state. Use `ReadOnlyBeanNotifier` to force the refresh of read-only beans.

To do this, invoke the following methods on the `ReadOnlyBeanNotifier` bean:

    public interface ReadOnlyBeanNotifier extends java.rmi.Remote {
       refresh(Object PrimaryKey) throws RemoteException;
     }

The implementation of the `ReadOnlyBeanNotifier` interface is provided by the container. The bean looks up `ReadOnlyBeanNotifier` using a fragment of code such as the following example:

    com.sun.appserv.ejb.ReadOnlyBeanHelper helper =
      new com.sun.appserv.ejb.ReadOnlyBeanHelper();
    com.sun.appserv.ejb.ReadOnlyBeanNotifier notifier =
      helper.getReadOnlyBeanNotifier("java:comp/env/ejb/ReadOnlyCustomer");
    notifier.refresh(PrimaryKey);

For a local read-only bean notifier, the lookup has this modification:

    helper.getReadOnlyBeanLocalNotifier("java:comp/env/ejb/LocalReadOnlyCustomer");

Beans that update any data that is cached by read-only beans need to call the `refresh` methods. The next (non-transactional) call to the read-only bean invokes `ejbLoad`.

Note –

Programmatic refresh of read-only beans is not supported in a clustered environment.

## Deploying Read Only Beans

Read-only beans are deployed in the same manner as other entity beans. However, in the entry for the bean in the `sun-ejb-jar.xml` file, the `is-read-only-bean` element must be set to true. That is:

`<is-read-only-bean>true</is-read-only-bean>`

Also, the `refresh-period-in-seconds` element in the `sun-ejb-jar.xml` file can be set to some value that specifies the rate at which the bean is refreshed. If this element is missing, no refresh occurs.

All requests in the same transaction context are routed to the same read-only bean instance. Set the `allow-concurrent-access` element to either `true` (to allow concurrent accesses) or `false` (to serialize concurrent access to the same read-only bean). The default is `false`.

For further information on these elements, refer to The sun-ejb-jar.xml File.

# Using Message-Driven Beans

This section describes message-driven beans and explains the requirements for creating them in the Application Server environment. This section contains the following topics:

- Message-Driven Bean Configuration

- Restrictions and Optimizations

- Sample Message-Driven Bean XML Files

## Message-Driven Bean Configuration

This section addresses the following configuration topics:

- Using Session Beans

- Message-Driven Bean Pool

- Domain-Level Settings

For information about setting up load balancing for message-driven beans, see Load-Balanced Message Inflow.

### Connection Factory and Destination

A message-driven bean is a client to a Connector 1.5 inbound resource adapter. The message-driven bean container uses the JMS service integrated into the Application Server for message-driven beans that are JMS clients. JMS clients use JMS Connection Factory- and Destination-administered objects. A JMS Connection Factory administered object is a resource manager Connection Factory object that is used to create connections to the JMS provider.

The `mdb-connection-factory` element in the `sun-ejb-jar.xml`file for a message-driven bean specifies the connection factory that creates the container connection to the JMS provider.

The `jndi-name` element of the `ejb` element in the `sun-ejb-jar.xml` file specifies the JNDI name of the administered object for the JMS `Queue` or `Topic` destination that is associated with the message-driven bean.

### Message-Driven Bean Pool

The container manages a pool of message-driven beans for the concurrent processing of a stream of messages. The `sun-ejb-jar.xml` file contains the elements that define the pool (that is, the `bean-pool` element):

- `steady-pool-size`

- `resize-quantity`

- `max-pool-size`

- `pool-idle-timeout-in-seconds`

For more information about `sun-ejb-jar.xml`, see The sun-ejb-jar.xml File.

### Domain-Level Settings

You can control the following domain-level message-driven bean settings in the EJB container:

- Initial and Minimum Pool Size - Specifies the initial and minimum number of beans maintained in the pool. The default is `0`.

- Maximum Pool Size - Specifies the maximum number of beans that can be created to satisfy client requests. The default is 3`2`.

- Pool Resize Quantity - Specifies the number of beans to be created if a request arrives when the pool is empty (subject to the Initial and Minimum Pool Size), or the number of beans to remove if idle for more than the Idle Timeout. The default is `8`.

- Idle Timeout - Specifies the maximum time in seconds that a bean can remain idle in the pool. After this amount of time, the bean is destroyed. The default is `600` (10 minutes). A value of `0` means a bean can remain idle indefinitely.

For information on monitoring message-driven beans, see the Application Server Administration Console online help and the Sun Java System Application Server Enterprise Edition 8.1 2005Q2 Administration Guide.

Note –

Running monitoring when it is not needed might impact performance, so you might choose to turn monitoring off when it is not in use. For details, see the Sun Java System Application Server Enterprise Edition 8.1 2005Q2 Administration Guide.

## Restrictions and Optimizations

This section discusses the following restrictions and performance optimizations that pertain to developing message-driven beans:

- Pool Tuning and Monitoring

- onMessage Runtime Exception

### Pool Tuning and Monitoring

The message-driven bean pool is also a pool of threads, with each message-driven bean instance in the pool associating with a server session, and each server session associating with a thread. Therefore, a large pool size also means a high number of threads, which impacts performance and server resources.

When configuring message-driven bean pool properties, make sure to consider factors such as message arrival rate and pattern, `onMessage` method processing time, overall server resources (threads, memory, and so on), and any concurrency requirements and limitations from other resources that the message-driven bean accesses.

When tuning performance and resource usage, make sure to consider potential JMS provider properties for the connection factory used by the container (the `mdb-connection-factory` element in the `sun-ejb-jar.xml` file). For example, you can tune the Sun Java System Message Queue flow control related properties for connection factory in situations where the message incoming rate is much higher than `max-pool-size` can handle.

Refer to the Sun Java System Application Server Enterprise Edition 8.1 2005Q2 Administration Guide for information on how to get message-driven bean pool statistics.

### onMessage Runtime Exception

Message-driven beans, like other well-behaved MessageListeners, should not, in general, throw runtime exceptions. If a message-driven bean’s `onMessage` method encounters a system-level exception or error that does not allow the method to successfully complete, the Enterprise JavaBeans Specification, v2.1 provides the following guidelines:

- If the bean method encounters a runtime exception or error, it should simply propagate the error from the bean method to the container.

- If the bean method performs an operation that results in a checked exception that the bean method cannot recover, the bean method should throw the `javax.ejb.EJBException` that wraps the original exception.

- Any other unexpected error conditions should be reported using `javax.ejb.EJBException` (`javax.ejb.EJBException` is a subclass of `java.lang.RuntimeException`).

Under container-managed transaction demarcation, upon receiving a runtime exception from a message-driven bean’s `onMessage` method, the container rolls back the container-started transaction and the message is redelivered. This is because the message delivery itself is part of the container-started transaction. By default, the Application Server container closes the container’s connection to the JMS provider when the first runtime exception is received from a message-driven bean instance’s `onMessage` method. This avoids potential message redelivery looping and protects server resources if the message-driven bean’s `onMessage` method continues misbehaving. To change this default container behavior, use the `cmt-max-runtime-exceptions` property of the `mdb-container` element in the `domain.xml` file.

The `cmt-max-runtime-exceptions` property specifies the maximum number of runtime exceptions allowed from a message-driven bean’s `onMessage` method before the container starts to close the container’s connection to the message source. By default this value is 1; -1 disables this container protection.

A message-driven bean’s `onMessage` method can use the `javax.jms.Message` `getJMSRedelivered` method to check whether a received message is a redelivered message.

Note –

The `cmt-max-runtime-exceptions` property might be deprecated in the future.

## Sample Message-Driven Bean XML Files

This section includes the following sample files:

- Sample ejb-jar.xml File

- Sample sun-ejb-jar.xml File

For general information on the `sun-ejb-jar.xml` file, see The sun-ejb-jar.xml File.

### Sample ejb-jar.xml File

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE ejb-jar PUBLIC '-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans
    2.0//EN' 'http://java.sun.com/dtd/ejb-jar_2_0.dtd'>
    <ejb-jar>
    <enterprise-beans>
    	<message-driven>
    		<ejb-name>MessageBean</ejb-name>
    		<ejb-class>samples.mdb.ejb.MessageBean</ejb-class>
    		<transaction-type>Container</transaction-type>
    		<message-driven-destination>
    			<destination-type>javax.jms.Queue</destination-type>
    		</message-driven-destination>
    		<resource-ref>
    			<res-ref-name>jms/QueueConnectionFactory</res-ref-name>
    			<res-type>javax.jms.QueueConnectionFactory</res-type>
    			<res-auth>Container</res-auth>
    		</resource-ref>
    	</message-driven>
    </enterprise-beans>
    	<assembly-descriptor>
    		<container-transaction>
    			<method>
    				<ejb-name>MessageBean</ejb-name>
    				<method-intf>Bean</method-intf>
    				<method-name>onMessage</method-name>
    				<method-params>
    					<method-param>javax.jms.Message</method-param>
    				</method-params>
    			</method>
    		<trans-attribute>NotSupported</trans-attribute>
    	</container-transaction>
    </assembly-descriptor
    </ejb-jar>

### Sample sun-ejb-jar.xml File

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE sun-ejb-jar PUBLIC '-//Sun Microsystems, Inc.//DTD Application
    Server 8.1 EJB 2.1//EN'
    'http://www.sun.com/software/appserver/dtds/sun-ejb-jar_2_1-1.dtd'>
    <sun-ejb-jar>
    <enterprise-beans>
    	<ejb>
    		<ejb-name>MessageBean</ejb-name>
    		<jndi-name>jms/sample/Queue</jndi-name>
    		<resource-ref>
    			<res-ref-name>jms/QueueConnectionFactory</res-ref-name>
    			<jndi-name>jms/sample/QueueConnectionFactory</jndi-name>
    			<default-resource-principal>
    				<name>guest</name>
    				<password>guest</password>
    			</default-resource-principal>
    		</resource-ref>
    		<mdb-connection-factory>
    			<jndi-name>jms/sample/QueueConnectionFactory</jndi-name>
    			<default-resource-principal>
    				<name>guest</name>
    				<password>guest</password>
    			</default-resource-principal>
    		</mdb-connection-factory>
    	</ejb>
    </enterprise-beans>
    </sun-ejb-jar>

# Handling Transactions with Enterprise Beans

This section describes the transaction support built into the Enterprise JavaBeans programming model for the Application Server.

As a developer, you can write an application that updates data in multiple databases distributed across multiple sites. The site might use EJB servers from different vendors. This section provides overview information on the following topics:

- Flat Transactions

- Global and Local Transactions

- Commit Options

- Administration and Monitoring

## Flat Transactions

The Enterprise JavaBeans Specification, v2.1 requires support for flat (as opposed to nested) transactions. In a flat transaction, each transaction is decoupled from and independent of other transactions in the system. Another transaction cannot start in the same thread until the current transaction ends.

Flat transactions are the most prevalent model and are supported by most commercial database systems. Although nested transactions offer a finer granularity of control over transactions, they are supported by far fewer commercial database systems.

## Global and Local Transactions

Understanding the distinction between global and local transactions is crucial in understanding the Application Server support for transactions. See Transaction Scope.

Both local and global transactions are demarcated using the `javax.transaction.UserTransaction` interface, which the client must use. Local transactions bypass the transaction manager and are faster. For more information, see Naming Environment for J2EE Application Components.

## Commit Options

The EJB protocol is designed to give the container the flexibility to select the disposition of the instance state at the time a transaction is committed. This allows the container to best manage caching an entity object’s state and associating an entity object identity with the EJB instances.

There are three commit-time options:

- Option A: The container caches a ready instance between transactions. The container ensures that the instance has exclusive access to the state of the object in persistent storage.

  In this case, the container does not have to synchronize the instance’s state from the persistent storage at the beginning of the next transaction.

  Note –

  Commit option A is not supported for this Application Server release.

- Option B: The container caches a ready instance between transactions, but the container does not ensure that the instance has exclusive access to the state of the object in persistent storage. This is the default.

  In this case, the container must synchronize the instance’s state by invoking `ejbLoad` from persistent storage at the beginning of the next transaction.

- Option C: The container does not cache a ready instance between transactions, but instead returns the instance to the pool of available instances after a transaction has completed.

  The life cycle for every business method invocation under commit option C looks like this:

      ejbActivate -> ejbLoad -> business method -> ejbStore -> ejbPassivate

  If there is more than one transactional client concurrently accessing the same entity `EJBObject`, the first client gets the ready instance and subsequent concurrent clients get new instances from the pool.

The Application Server deployment descriptor has an element, `commit-option`, that specifies the commit option to be used. Based on the specified commit option, the appropriate handler is instantiated.

## Administration and Monitoring

An administrator can control a number of domain-level Transaction Service settings. For details, see Configuring the Transaction Service.

The Transaction Timeout setting can be overridden by a bean. See Bean-Level Container-Managed Transaction Timeouts.

In addition, the administrator can monitor transactions using statistics from the transaction manager that provide information on such activities as the number of transactions completed, rolled back, or recovered since server startup, and transactions presently being processed.

For information on administering and monitoring transactions, see the Application Server Administration Console online help and the Sun Java System Application Server Enterprise Edition 8.1 2005Q2 Administration Guide.

- Previous: Chapter 5 Developing Web Applications
- Next: Chapter 7 Using Container-Managed Persistence for Entity Beans

- © 2010, Oracle Corporation and/or its affiliates