bea.com | products | dev2dev | support | askBEA

Download Docs | Site Map | Glossary
Search

Programming WebLogic Enterprise JavaBeans

The WebLogic Server EJB Container and Supported Services

The following sections describe the WebLogic Server EJB container, plus various aspects of EJB behavior in terms of the features and services that the container provides. See WebLogic Server Container-Managed Persistence Service, for more information on container-managed persistence (CMP).

- EJB Container

- EJB Life Cycle

- ejbLoad() and ejbStore() Behavior for Entity EJBs

- EJB Concurrency Strategy

- Combined Caching with Entity Beans

- Caching Between Transactions

- EJBs in WebLogic Server Clusters

- Transaction Management

- Database Insert Support

- Resource Factories

EJB Container

The EJB container is a runtime container for deployed EJBs. It is automatically created when WebLogic Server is started. During the entire life cycle of an EJB object, from its creations to removal, it lives in the container. The EJB container provides a standard set of services, including caching, concurrency, persistence, security, transaction management, locking, environment, memory replication, and clustering for the EJB objects that live in the container.

You can deploy multiple beans in a single container. For each session and entity bean deployed in a container, the container provides a home interface. The home interface allows a client to create, find, and remove entity objects that belong to the entity bean as well as to execute home business methods which are not specific to a particular entity bean object. A client can look up the entity bean's home interface through the Java Naming and Directory Interface (JNDI) or by following an EJB reference, which is preferred. The container is responsible for making the entity bean's home interface available in the JNDI name space. For instructions on looking up the home interface through JNDI, see Programming WebLogic JNDI.

EJB Life Cycle

The following sections provide information about how the container supports caching services. They describe the life cycle of EJB instances in WebLogic Server, from the perspective of the server. These sections use the term EJB instance to refer to an actual instance of the EJB bean class. EJB instance does not refer to the logical instance of the EJB as seen from the point of view of a client.

Entity Bean Lifecycle and Caching and Pooling

WebLogic Server provides these features to improve performance and throughput for entity EJBs:

- Free pool—stores anonymous entity beans that are used for invoking finders, home methods, and creating entity beans.

- Cache—contains instances that have an identity—a primary key, or are currently enlisted in a transaction (READY and ACTIVE entity EJB instances).

The sections that follow describe the lifecycle of an entity bean instance, and how the container populates and manages the free pool and the cache. For an illustration, see Figure 4-2.

Initializing Entity EJB Instances (Free Pool)

If you specify a non-zero value for initial-beans-in-free-pool, WebLogic Server populates the pool with the specified quantity of bean instances at startup.

The default value of initial-beans-in-free-pool is zero. Populating the free pool at startup improves initial response time for the EJB, because initial requests for the bean can be satisfied without generating a new instance.

An attempt to obtain an entity bean instance from the free pool will always succeed, even if the pool is empty. If the pool is empty, a new bean instance is be created and returned.

POOLED beans are anonymous instances, and are used for finders and home methods. The maximum number of instances the pool can contain is specified by the value of the max-beans-in-free-pool element in weblogic-ejb-jar.xml.

READY and ACTIVE Entity EJB Instances (Cache)

When a business method is called on a bean, the container obtains an instance from the pool, calls ejbActivate, and the instance services the method call.

A READY instance is in the cache, has an identity—an associated primary key, but is not currently enlisted in a transaction. WebLogic maintains READY entity EJB instances in least-recently-used (LRU) order. Current Beans in Cache field in the monitoring tab displays the count of active and ready beans.

An ACTIVE instance is currently enlisted in a transaction. After completing the transaction, the instance becomes READY, and remains in cache until space is needed for other beans.

The effect of max-beans-in-cache, and the quantity of instances with the same primary key allowed in the cache vary by concurrency strategy, as described in the following section, Cache Rules Vary by Concurrency Strategy.

Cache Rules Vary by Concurrency Strategy

Table 4-1 lists, for each concurrency strategy:

- How the value of the max-beans-in-cache element in weblogic-ejb-jar.xml limits the number of entity bean instances in the cache.

- How many entity bean instances with the same primary key are allowed in the cache.

  Figure 4-1 Entity EJB Caching Behavior by Concurrency Type

  Concurrency Option | What is the effect of max-beans-in-cache on the number of bean instances in the cache? | How many instances with same primary key can exist in cache simultaneously?
  --- | --- | ---
  Exclusive | max-beans-in-cache = number of ACTIVE bean + number of READY instances. | one
  Database | The cache can contain up to max-beans-in-cache ACTIVE bean instances and up to max-beans-in-cache READY bean instances. | multiple
  ReadOnly | max-beans-in-cache = number of ACTIVE bean + number of READY instances. | one

Removing Beans from Cache

READY entity EJB instances are removed from the cache when the space is needed for other beans. When a READY instance is removed from cache, ejbPassivate is called on the bean, and the container will try to put it back into the free pool.

When the container tries to return an instance to the free pool and the pool already contains max-beans-in-free-pool instances, the instance is discarded.

ACTIVE entity EJB instances will not be removed from cache until the transaction they are participating in commits or rolls back, at which point they will become READY, and hence eligible for removal from the cache.

Entity EJB Lifecycle Transitions

Figure 4-2 illustrates the EJB free pool and cache, and the transitions that occur throughout an entity bean instance's lifecycle.

Figure 4-2 Entity Bean Lifecycle

Stateless Session EJB Life Cycle

WebLogic Server uses a free pool to improve performance and throughput for stateless session EJBs. The free pool stores unbound stateless session EJBs. Unbound EJB instances are instances of a stateless session EJB class that are not processing a method call.

The following figure illustrates the WebLogic Server free pool, and the processes by which stateless EJBs enter and leave the pool. Dotted lines indicate the "state" of the EJB from the perspective of WebLogic Server.

Figure 4-3 WebLogic Server free pool showing stateless session EJB life cycle

Initializing Stateless Session EJB Instances

By default, no stateless session EJB instances exist in WebLogic Server at startup time. As clients access individual beans, WebLogic Server initializes new instances of the EJB. However, if you want inactive instances of the EJB to exist in WebLogic Server when it is started, specify how many in the initial-beans-in-free-pool deployment descriptor element, in the weblogic-ejb-jar.xml file.

This can improve initial response time when clients access EJBs, because initial client requests can be satisfied by activating the bean from the free pool (rather than initializing the bean and then activating it). By default, initial-beans-in-free-pool is set to 0.

Note: The maximum size of the free pool is limited by the value of the max-beans-in-free-pool deployment element, available memory, or the number of execute threads.

Activating and Pooling Stateless Session EJBs

When a client calls a method on a stateless session EJB, WebLogic Server obtains an instance from the free pool. The EJB remains active for the duration of the client's method call. After the method completes, the EJB instance is returned to the free pool. Because WebLogic Server unbinds stateless session beans from clients after each method call, the actual bean class instance that a client uses may be different from invocation to invocation.

If all instances of an EJB class are active and max-beans-in-free-pool has been reached, new clients requesting the EJB class will be blocked until an active EJB completes a method call. If the transaction times out (or, for non-transactional calls, if five minutes elapse), WebLogic Server throws a RemoteException for a remote client or an EJBException for a local client.

Stateful Session EJB Life Cycle

WebLogic Server uses a cache of bean instances to improve the performance of stateful session EJBs. The cache stores active EJB instances in memory so that they are immediately available for client requests. The cache contains EJBs that are currently in use by a client and instances that were recently in use. Stateful session beans in cache are bound to a particular client.

The following figure illustrates the WebLogic Server cache, and the processes by which stateful EJBs enter and leave the cache.

Figure 4-4 Stateful Session EJB Life Cycle

Stateful Session EJB Creation

No stateful session EJB instances exist in WebLogic Server at startup. Before a client begins accessing a stateful session bean, it creates a new bean instance to use during its session with the bean. When the session is over the instance is destroyed. While the session is in progress, the instance is cached in memory.

Stateful Session EJB Passivation

Passivation is the process by which WebLogic Server removes an EJB instance from cache while preserving its state on disk. While passivated, EJBs are not in memory and are not immediately available for client requests, as they are when in the cache.

The EJB developer must ensure that a call to the ejbPassivate() method leaves a stateful session bean in a condition such that WebLogic Server can serialize its data and passivate the instance. During passivation, WebLogic Server attempts to serialize any fields that are not declared transient. This means that you must ensure that all non-transient fields represent serializable objects, such as the bean's remote or home interface. EJB 2.1 specifies the field types that are allowed.

Controlling Passivation

The rules that govern the passivation of stateful session beans vary, based on the value of the beans cache-type element, which can be:

- LRU—least recently used, referred to as eager passivation.

- NRU—not recently used, referred to as lazy passivation

The idle-timeout-seconds and max-beans-in-cache elements also affect passivation and removal behaviors, based on the value of cache-type.

Eager Passivation (LRU)

When you configure eager passivation for a stateful session bean by setting cache-type to LRU, the container:

- Passivates instances to disk:

  - as soon as an instance has been inactive for idle-timeout-seconds, regardless of the value of max-beans-in-cache.

  - when max-beans-in-cache is reached, even though idle-timeout-seconds has not expired.

- Removes a passivated instance from disk after it has been inactive for idle-timeout-seconds after passivation.

Lazy Passivation (NRU)

When lazy passivation is configured by setting cache-type to NRU, the container avoids passivating beans, because of the associated systems overhead—pressure on the cache is the only event that causes passivation or eager removal of beans.

The container:

- Removes a bean instance from cache when idle-timeout-seconds expires, and does not passivate it to disk. This is referred to as a eager remove. An eager remove ensures that an inactive instance does not consume memory or disk resources.

- Passivates instances to disk when max-beans-in-cache is reached, even though idle-timeout-seconds has not expired.

Preventing Removal of Idle EJBs

Setting idle-timeout-seconds to 0 stops WebLogic Server from removing EJBs that are idle for a period of time. However, EJBs may still be passivated if cache resources become scarce.

Managing EJB Cache Size

For a discussion of managing cache size to optimize performance in a production environment see "Setting EJB Pool Size" in WebLogic Server Performance and Tuning.

Specifying the Persistent Store Directory for Passivated Beans

When a stateful session bean is passivated, its state is stored in a file system directory. Each server instance has its own directory for storing the state of passivated stateful session beans, known as the persistent store directory. The persistent store directory contains one subdirectory for each passivated bean.

The persistent store directory is created by default in the server instance directory, for example:

D:\releases\700\bea\user_domains\mydomain\myserver\pstore\

The path to the persistence store is:

RootDirectory\ServerName\persistent-store-dir

where:

- RootDirectory—the directory where WebLogic Server runs, for example:

  D:\releases\700\bea\user_domains\mydomain

  RootDirectory can be specified at server startup with the -Dweblogic.RootDirectory property.

- ServerName—the name of the server instance.

- persistent-store-dir—the value of the of the persistent-store-dir element in the <stateful-session-descriptor> stanza of weblogic-ejb-jar.xml. If no value is specified for <persistent-store-dir>, the directory is named pstore by default.

The persistent store directory contains a subdirectory, named with a hash code, for each passivated bean. For example, the subdirectory for a passivated bean in the example above might be:

D:\releases\700\bea\user_domains\mydomain\myserver\pstore\14t89gex0m2fr

Concurrent Access to Stateful Session Beans

In accordance with the EJB 2.0 specification, simultaneous access to a stateful session EJB results in a RemoteException. This access restriction on stateful session EJBs applies whether the EJB client is remote or internal to WebLogic Server. To override this restriction and configure a stateful session bean to allow concurrent calls, set the allow-concurrent-calls deployment element.

If multiple servlet classes access a stateful session EJB, each servlet thread (rather than each instance of the servlet class) must have its own session EJB instance. To prevent concurrent access, a JSP/servlet can use a stateful session bean in request scope.

ejbLoad() and ejbStore() Behavior for Entity EJBs

WebLogic Server reads and writes the persistent fields of entity EJBs using calls to ejbLoad() and ejbStore(). By default, WebLogic Server calls ejbLoad() and ejbStore() in the following manner:

1. A transaction is initiated for the entity EJB. The client may explicitly initiate a new transaction and invoke the bean, or WebLogic Server may initiate a new transaction in accordance with the bean's method transaction attributes.

2. WebLogic Server calls ejbLoad() to read the most current version of the bean's persistent data from the underlying datastore.

3. When the transaction commits, WebLogic Server calls ejbStore() to write persistent fields back to the underlying datastore.

This simple process of calling ejbLoad() and ejbStore() ensures that new transactions always use the latest version of the EJB's persistent data, and always write the data back to the datastore upon committing. In certain circumstances, however, you may want to limit calls to ejbLoad() and ejbStore() for performance reasons. Alternately, you may want to call ejbStore() more frequently to view the intermediate results of uncommitted transactions.

WebLogic Server provides several deployment descriptor elements in the weblogic-ejb-jar.xml and weblogic-cmp-rdbms-jar.xml files that enable you to configure ejbLoad() and ejbStore() behavior.

Using is-modified-method-name to Limit Calls to ejbStore() (EJB 1.1 Only)

The is-modified-method-name deployment descriptor element applies to EJB 1.1 container-managed-persistence (CMP) beans only. This element is found in the weblogic-ejb-jar.xml file. WebLogic Server CMP implementation automatically detects modifications of CMP fields and writes only those changes to the underlying datastore. We recommend that you do not use is-modified-method-name with bean-managed-persistence (BMP) because you would need to create both the is-modified-method-name element. and the ejbstore method.

By default, WebLogic Server calls the ejbStore() method at the successful completion (commit) of each transaction. ejbStore() is called at commit time regardless of whether the EJB's persistent fields were actually updated, and results in a DBMS update. WebLogic Server provides the is-modified-method-name element for cases where unnecessary calls to ejbStore() may result in poor performance.

To use is-modified-method-name, EJB providers must first develop an EJB method that "cues" WebLogic Server when persistent data has been updated. The method must return "false" to indicate that no EJB fields were updated, or "true" to indicate that some fields were modified.

The EJB provider or EJB deployment descriptors then identify the name of this method by using the value of the is-modified-method-name element. WebLogic Server calls the specified method name when a transaction commits, and calls ejbStore() only if the method returns "true." For more information on this element, see is-modified-method-name.

Warning for is-modified-method-name

Using the is-modified-method-name element can improve performance by avoiding unnecessary calls to ejbStore(). However, it places a greater burden on the EJB developer to identify correctly when updates have occurred. If the specified is-modified-method-name returns an incorrect flag to WebLogic Server, data integrity problems can occur, and they may be difficult to track down.

If entity EJB updates appear "lost" in your system, start by ensuring that the value for all is-modified-method-name elements return "true" under every circumstance. In this way, you can revert to WebLogic Server's default ejbStore() behavior and possibly correct the problem.

Using delay-updates-until-end-of-tx to Change ejbStore() Behavior

By default, WebLogic Server updates the persistent store of all beans in a transaction only at the completion (commit) of the transaction. This generally improves performance by avoiding unnecessary updates and repeated calls to ejbStore().

If your datastore uses an isolation level of READ_UNCOMMITTED, you may want to allow other database users to view the intermediate results of in-progress transactions. In this case, the default WebLogic Server behavior of updating the datastore only at transaction completion may be unacceptable.

You can disable the default behavior by using the delay-updates-until-end-of-tx deployment descriptor element. This element is set in the weblogic-ejb-jar.xml file. When you set this element to "false," WebLogic Server calls ejbStore() after each method call, rather than at the conclusion of the transaction.

Note: Setting delay-updates-until-end-of-tx to false does not cause database updates to be "committed" to the database after each method invoke; they are only sent to the database. Updates are committed or rolled back in the database only at the conclusion of the transaction.

EJB Concurrency Strategy

The concurrency strategy specifies how the EJB container should manage concurrent access to an entity bean. Although the Database option is the default concurrency strategy for WebLogic Server, you may want to specify other options for your entity bean depending on the type of concurrency access the bean requires. WebLogic Server provides the following concurrency strategy options:

Concurrency Option | Description
--- | ---
Exclusive | Places an exclusive lock on cached entity EJB instances when the bean is associated with a transaction. Other requests for the EJB instance are block until the transaction completes. This option was the default locking behavior for WebLogic Server versions 3.1 through 5.1
Database | Defers locking requests for an entity EJB to the underlying datastore. WebLogic Server allocates a separate entity bean instance and allows locking and caching to be handled by the database. This is the default option.
Optimistic | Holds no locks in the EJB container or database during a transaction. The EJB container verifies that none the data updated by the transaction has changed before committing the transaction. If any updated data changed, the EJB container rolls back the transaction.
ReadOnly | Used only for read-only entity beans. Activates a new instance for each transaction so that requests proceed in parallel. WebLogic Server calls ejbLoad() for ReadOnly beans are based on the read-timeout-seconds parameter.

Concurrency Strategy for Read-Write EJBs

You can use the Exclusive, Database, and Optimistic concurrency strategies for read-write EJBs. WebLogic Server loads EJB data into the cache at the beginning of each transaction, or as described in Using cache-between-transactions to Limit Calls to ejbLoad(). WebLogic Server calls ejbStore() at the successful commit of a transaction, or as described under Using is-modified-method-name to Limit Calls to ejbStore() (EJB 1.1 Only).

Specifying the Concurrency Strategy

You specify the locking mechanism that the EJB uses by setting the concurrency-strategy deployment parameter in weblogic-ejb-jar.xml. You set concurrency-strategy at the individual EJB level, so that you can mix locking mechanisms within the EJB container.

The following excerpt from weblogic-ejb-jar.xml shows how to set the concurrency strategy for an EJB. In the following sample XML, the code specifies the default locking mechanism, Database.

Figure 4-5 Sample XML specifying the concurrency strategy

>     <entity-descriptor>
>     	<entity-cache>
>     	...
>     	<concurrency-strategy>Database</concurrency-strategy>
>     	</entity-cache>
>     	...
>     </entity-descriptor>

If you do not specify a concurrency-strategy, WebLogic Server performs database locking for entity EJB instances.

A description of each concurrency strategy is covered in the following sections.

Exclusive Concurrency Strategy

The Exclusive concurrency strategy was the default in WebLogic Server 5.1 and 4.5.1. This locking method provides reliable access to EJB data, and avoids unnecessary calls to ejbLoad() to refresh the EJB instance's persistent fields. However, exclusive locking does not provide the best model for concurrent access to the EJB's data. Once a client has locked an EJB instance, other clients are blocked from the EJB's data even if they intend only to read the persistent fields.

The EJB container in WebLogic Server can use exclusive locking mechanism for entity EJB instances. As clients enlist an EJB or EJB method in a transaction, WebLogic Server places an exclusive lock on the EJB instance for the duration of the transaction. Other clients requesting the same EJB or method are blocked until the current transaction completes.

Database Concurrency Strategy

The Database concurrency strategy is the default option for WebLogic Server and the recommended mechanism for EJB 1.1 and EJB 2.0 beans. It improves concurrent access for entity EJBs. The WebLogic Server container defers locking services to the underlying database. Unlike exclusive locking, the underlying data store can provide finer granularity for locking EJB data, and deadlock detection.

With the database locking mechanism, the EJB container continues to cache instances of entity EJB classes. However, the container does not cache the intermediate state of the EJB instance between transactions. Instead, WebLogic Server calls ejbLoad() for each instance at the beginning of a transaction to obtain the latest EJB data. The request to commit data is subsequently passed along to the database. The database, therefore, handles all lock management and deadlock detection for the EJB's data.

Deferring locks to the underlying database improves throughput for concurrent access to entity EJB data, while also providing deadlock detection. However, using database locking requires more detailed knowledge of the underlying datastore's lock policies, which can reduce the EJB's portability among different systems.

When using the Database concurrency strategy instead of Optimistic with the cache-between-transactions element set to "True," you will receive a warning message from the compiler indicating that cache-between-transactions should be disabled. If this condition exists, WebLogic Server automatically disables cache-between-transactions.

Optimistic Concurrency Strategy

The Optimistic concurrency strategy does not hold any locks in the EJB container or the database while the transaction is in process. When you specify this option, the EJB container ensures that the data being updated by a transaction has not changed. It performs a "smart update" by checking the fields before it commits the transaction.

Note: The EJB container does not check Blob/Clob fields for optimistic concurrency. The work-around is to use version or timestamp checking.

Limitations of Optimistic Concurrency

If you use optimistic concurrency, BEA recommends that the include-updates element in weblogic-cmp-jar.xml be set to false. Using optimistic concurrency with include-updates set to true is inefficient—it is equivalent to using pessimistic concurrency. If you need to set include-updates true, use the database concurrency strategy.

Using optimistic concurrency with include-updates set to true is not supported for databases that hold locks during transactions (non-Oracle databases) This is because: optimistic transactions read using a local transaction to avoid holding locks until the end of the transaction. However, optimistic transactions write using the current JTA transaction so that the updates can be rolled back, if necessary. In general, updates made by the JTA transaction are not visible to the read transactions until the JTA transaction commits.

Check Data for Validity with Optimistic Concurrency

You can configure the EJB container to validate an Optimistic bean's transaction data before committing the transaction, to verify that no data read or updated by the transaction has bean changed by another transaction. If it detects changed data, the EJB container rolls back the transaction.

Note: The EJB container does not validate Blob or Clob fields in a bean with Optimistic concurrency. The work-around is to use version or timestamp checking.

Configuring Optimistic Checking

Configure validity checking for a bean with Optimistic concurrency using the verify-columns element in the table-name stanza for the bean in weblogic-cmp-jar.xml.

The verify-columns element specifies how columns in a table are checked for validity when you use the optimistic concurrency strategy.

1. Set the value of the verify-columns element to:

- Read—to check all columns in the table that have been read during the transaction. This includes both rows that are simply read and rows that are read and then updated or deleted by the transaction.

- Modified—to check only the columns that have been updated or deleted by the current transaction.

- Version—to check that a version column exists in the table and that this column is used to implement optimistic concurrency.

  A version column must be created with an initial value of 0, and must increment by 1 whenever the row is modified.

- Timestamp—to check that a timestamp column exists in the table and that this column is used to implement optimistic concurrency. Timestamp-based optimistic concurrency requires a 1 second granularity for the database column.

The EJB container manages the version or timestamp column, updating its value as appropriate upon completion of the transaction.

Note: The version or timestamp column is not updated if the transaction did not modify and regular CMP or CMR fields—if the only data changed during the transaction was the value of the version or timestamp column (as a result of transaction initiation) the column used for optimistic checking will not be updated at the end of the transaction.

1. If verify-columns is set to Version or Timestamp, specify the version or timestamp column using the optimistic-column in the table-map stanza in the weblogic-cmp-jar.xml file. Mapping this column to a cmp-field is optional.

   The optimistic-column element identifies a database column that contains a version or timestamp value used to implement optimistic concurrency. This element is case maintaining, though not all databases are case sensitive. The value of this element is ignored unless verify-columns is set to Version or Timestamp.

If the EJB is mapped to multiple tables, optimistic checking is only performed on the tables that are updated during the transaction.

By default, caching between transactions is not enabled for optimistic beans. You must explicitly enable it. See Using cache-between-transactions to Limit Calls to ejbLoad(). When you enable long term caching for an entity bean with an optimistic concurrency strategy the EJB container reuses the cached values from previous transactions. The container ensures that the updates are transactionally consistent by checking for optimistic conflicts at the end of the transaction. In addition, notifications for updates of optimistic data are broadcast to other cluster members to help avoid optimistic conflicts and keep cached data fresh.

Optimistic Checking and Oracle Databases

For Oracle databases, if you set verify-columns to Modified for an entity EJB with a CMP non-key field type java.util.Date and implementation type Oracle DATE, WebLogic Server throws an optimistic concurrency violation exception when a simple update is made to the non-key DATE field—even though only one user is updating the record.

This problem occurs because of a mismatch in date value precision between the Oracle DATE column and the java.util.Date type. The java.util.Date type is in milliseconds, and the Oracle DATE column is not. There are two ways to avoid this error:

- Set the Oracle database column type to Timestamp, a higher precision type introduced in Oracle9i.

- Include logic in your application to zero out the milliseconds of a java.util.Date value. To accomplish this, prepare a date field for an entity bean java.util.Date field in this way:

  Calendar cal = Calendar.getInstance();
  cal.set(Calendar.MILLISECOND, 0); // clears millisecond
  Date myDate = cal.getTime();

ReadOnly Concurrency Strategy

WebLogic Server provides support for concurrent access to read-only entity beans. This concurrency strategy activates an instance of a read-only entity bean for each transaction so that requests may be processed in parallel.

Prior to WebLogic Server 7.0 read-only entity beans used the exclusive locking concurrency strategy. This strategy places an exclusive lock on cached entity bean instances when the bean is associated with a transaction. Other requests for the entity bean instance are block until the transaction completes.

To avoid reading from the database, WebLogic Server copies the state for an EJB 2.0 CMP bean from the existing instance in the cache. For this release, the default concurrency strategy for read-only entity beans is the ReadOnly option.

You can specify read-only entity bean caching at the application-level or the component-level.

To enable read-only entity bean caching:

1. Specify the ReadOnly option in the concurrency-strategy deployment descriptor element for either a JAR file or an EAR file.

   - Specify the concurrency-strategy element for application-level caches (EARS) in the entity-cache-ref element in the weblogic-ejb-jar.xml file.

   - Specify the concurrency-strategy element for component-level caches (JARS) in the weblogic-ejb-jar.xml file.

2. For instructions on specifying deployment descriptors, see Specifying and Editing the EJB Deployment Descriptors.

Read-Only Entity Beans and ReadOnly Concurrency

Previous versions of read-only entity beans will work in this version of WebLogic Server. As in previous versions, you can set the read-timeout-seconds element set in weblogic-ejb-jar.xml. If an EJB's concurrency strategy is ReadOnly and read-timeout-seconds is set, when a read-only bean is invoked, WebLogic Server checks whether the cached data is older than the read-timeout-seconds setting. If it is, the bean's ejbLoad is called. Otherwise, the cached data is used.

Restrictions for ReadOnly Concurrency Strategy

Entity EJBs using the read-only concurrency strategy must observe the following restrictions:

- They cannot require updates to the EJB data, because WebLogic Server never calls ejbStore() for read-only entity EJBs.

- The EJB's method calls must be idempotent. See Stateless Session EJBs in a Cluster for more information.

- Because the bean's underlying data may be updated by an external source, calls to ejbLoad() are governed by the deployment parameter, read-timeout-seconds.

Read-Only Multicast Invalidation

Read-only multicast invalidation is an efficient means of invalidating cached data.

Invalidate a read-only entity bean by calling the following invalidate() method on either the CachingHome or CachingLocalHome interface:

Figure 4-6 Sample code showing CachingHome and CachingLocalHome interfaces

>     package weblogic.ejb;

>     public interface CachingHome {

>     	public void invalidate(Object pk) throws RemoteException;
>     	public void invalidate (Collection pks) throws RemoteException;
>     	public void invalidateAll() throws RemoteException;

>     public interface CachingLocalHome {

>     	public void invalidate(Object pk) throws RemoteException;
>     	public void invalidate (Collection pks) throws RemoteException;
>     	public void invalidateAll() throws RemoteException

>     }

The following example codes shows how to cast the home to CachingHome and then call the method:

Figure 4-7 Sample code showing how to cast the home and call the method

>     import javax.naming.InitialContext;
>     import weblogic.ejb.CachingHome;

>     Context initial = new InitialContext();
>     Object o = initial.lookup("CustomerEJB_CustomerHome");
>     CustomerHome customerHome = (CustomerHome)o;

>     CachingHome customerCaching = (CachingHome)customerHome;
>     customerCaching.invalidateAll();

When the invalidate() method is called, the read-only entity beans are invalidated in the local server, and a multicast message is sent to the other servers in the cluster to invalidate their cached copies. The next call to an invalidated read-only entity bean causes ejbLoad to be called. ejbLoad() reads the most current version of the persistent data from the underlying datastore

WebLogic Server calls the invalidate() method after the transaction update has completed. If the invalidation occurs during a transaction update, the previous version may be read if the isolation level does not permit reading uncommitted data.

Read-Mostly Pattern

WebLogic Server does not support a read-mostly cache strategy setting in weblogic-ejb-jar.xml. However, if you have EJB data that is only occasionally updated, you can create a "read-mostly pattern" by implementing a combination of read-only and read-write EJBs.

For an example of the read-mostly pattern, see the Read Mostly example in your WebLogic Server distribution:

%SAMPLES_HOME%/server/config/examples/ejb/extensions/readMostly

WebLogic Server provides an automatic invalidate() method for the Read-Mostly pattern. With this pattern, Read-Only entity bean and a Read-Write entity bean are mapped to the same data. To read the data, you use the Read-Only entity bean; to update the data, you use the Read-Write entity bean.

In a read-mostly pattern, a read-only entity EJB retrieves bean data at intervals specified by the read-timeout-seconds deployment descriptor element specified in the weblogic-ejb-jar.xml file. A separate read-write entity EJB models the same data as the read-only EJB, and updates the data at required intervals.

When creating a read-mostly pattern, use the following suggestions to reduce data consistency problems:

- For all read-only EJBs, set read-timeout-seconds to the same value for all beans that may be updated in the same transaction.

- For all read-only EJBs, set read-timeout-seconds to the smallest timeframe that yields acceptable performance levels.

- Ensure that all read-write EJBs in the system update only the smallest portion of data necessary; avoid beans that write numerous, unchanged fields to the datastore at each ejbStore().

- Ensure that all read-write EJBs update their data in a timely fashion; avoid involving read-write beans in long-running transactions that may span the read-timeout-seconds setting for their read-only counterparts.

  If you are running EJB 2.0, you can approximate the read-mostly pattern using a single bean that uses optimistic concurrency. An optimistic bean acts like a read-only beans when performing a read—it reads from the cache and can return stale data. However, when an optimistic bean performs a write, the container ensures that the data being updated has not changed—providing the same level of consistency for writes as a bean that uses Database concurrency. See Optimistic Concurrency Strategy.

Note: In a WebLogic Server cluster, clients of the read-only EJB benefit from using cached EJB data. Clients of the read-write EJB benefit from true transactional behavior, because the read-write EJB's state always matches the state of its data in the underlying datastore. See Entity EJBs in a Cluster for more information.

Combined Caching with Entity Beans

Combined caching allows multiple entity beans that are part of the same J2EE application to share a single runtime cache. Previously, you had to configure a separate cache for each entity bean that was part of an application. This caused some usability and performance problems in that it took more time to configure caches for each entity bean and more memory to run the application. This feature will help solve those problems.

To configure an application level cache:

1. Verify that the weblogic-application.xml file is located in the META-INF directory of the EAR file.

2. Provide an entry in the weblogic-application.xml file as follows:

   >     <weblogic-application>
   >     	<ejb>
   >     		<entity-cache>
   >     			<entity-cache-name>large_account</entity-cache-name>
   >     			<max-cache-size>
   >     				<megabytes>1</megabytes>
   >     			</max-cache-size>
   >     		</entity-cache>
   >     	</ejb>
   >     </weblogic_application>

   Use the entity-cache element to define a named application level cache that will be used to cache entity bean instances at runtime. There are no restrictions on the number of different entity beans that may reference an individual cache.

   The sub elements of entity-cache have the same basic meaning as they do in the weblogic-ejb-jar.xml deployment descriptor file.

3. Specify an entity-descriptor element in weblogic-ejb-jar.xml file.

   Use the entity-descriptor element to configure an entity bean to use an application level cache.

For instructions on specifying deployment descriptors, see Specifying and Editing the EJB Deployment Descriptors.

The weblogic-application.xml deployment descriptor is documented in full in the "Application.xml Deployment Descriptor Elements" section of Developing WebLogic Server Applications.

Caching Between Transactions

Use caching between transactions or long tern caching to enable the EJB container to cache an entity bean's persistent data between transactions. Whether you can set caching between transactions for an entity bean depends on its concurrency strategy, as summarized in the following three tables:

Table 4-1 Permitted cache-between-transactions values, by concurrency strategy, for BMP beans

A BMP bean using this concurrency strategy | Can set cache-between-transactions to
--- | ---
Database | False only
Exclusive | True or False
Read-Only | True or False
Optimistic | Not applicable. Optimistic concurrency is not available for BMP beans.

Table 4-2 Permitted cache-between-transactions values, by concurrency strategy, for CMP 2.0 beans

A CMP 2.0 bean using this concurrency strategy | Can set cache-between-transactions to this value
--- | ---
Database | True only
Exclusive | True or False
Read-Only | True or False
Optimistic | True or False

Table 4-3 Permitted cache-between-transactions values, by concurrency strategy, for CMP 1.1 beans

A CMP 1.1 bean using this concurrency strategy | Can set cache-between-transactions to this value
--- | ---
Database | True only
Exclusive | True or False
Read-Only | True or False
Optimistic | Not applicable. Optimistic concurrency is not available for CMP 1.1 beans.

Caching Between Transactions with Exclusive Concurrency

When you enable long term caching for an entity bean with an Exclusive concurrency strategy the EJB container must have exclusive update access to the underlying data. This means that another application outside of the EJB container must not be updating the data. If you deploy an EJB with an Exclusive concurrency strategy in a cluster, long term caching is disabled automatically because any node in the cluster may update the data. This would make long term caching impossible.

In previous versions of WebLogic Server, this feature was controlled by the db-is-shared element of weblogic-ejb-jar.xml.

Note: Exclusive concurrency is a single-server feature. Do not attempt to use it with clustered servers.

Caching Between Transactions with ReadOnly Concurrency

When you disable long term caching for an entity bean with a ReadOnly concurrency strategy it ignores the value of the cache-between-transactions setting because the EJB container always performs long term caching of read-only data.

Caching Between Transactions with Optimistic Concurrency

When you enable long term caching for an entity bean with an Optimistic concurrency strategy the EJB container reuses the cached values from previous transactions. The container ensures that the updates are transactionally consistent by checking for optimistic conflicts at the end of the transaction. See Optimistic Concurrency Strategy for instructions on setting optimistic checking.

In addition, notifications for updates of optimistic data are broadcast to other cluster members to help avoid optimistic conflicts.

Enabling Caching Between Transactions

To enable caching between transactions:

1. Set the cache-between-transactions element in the weblogic-ejb-jar.xml file by choosing one of the following options:

   - Specify True to enable the EJB container performs long term caching of the data.

   - Specify False to enable the EJB container performs short caching of the data. This is the default setting.

2. For instructions on specifying deployment descriptors, see Specifying and Editing the EJB Deployment Descriptors.

Using cache-between-transactions to Limit Calls to ejbLoad()

WebLogic Server's default behavior of calling ejbLoad() at the start of each transaction works well for environments where multiple sources may update the datastore. Because multiple clients (including WebLogic Server) may be modifying an EJB's underlying data, an initial call to ejbLoad() notifies the bean that it needs to refresh its cached data and ensures that it works against the most current version of the data.

In the special circumstance where only a single WebLogic Server transaction ever accesses a particular EJB concurrently, such as when you use exclusive concurrency for a single server; not a cluster, calling ejbLoad() by default is unnecessary. Because no other clients or systems update the EJB's underlying data, WebLogic Server's cached version of the EJB data is always up-to-date. Calling ejbLoad() in this case simply creates extra overhead for WebLogic Server clients that access the bean.

To avoid unnecessary calls to ejbLoad() in the case of a single WebLogic Server transaction accessing a particular EJB, WebLogic Server provides the cache-between-transactions deployment parameter. By default, cache-between-transactions is set to "false" for each EJB in the bean's weblogic-ejb-jar.xml file, which ensures that ejbLoad() is called at the start of each transaction. Where only a single WebLogic Server transaction ever accesses an EJB's underlying data concurrently, you can set d to "true" in the bean's weblogic-ejb-jar.xml file. When you deploy an EJB with cache-between-transactions set to "true," the single instance of WebLogic Server calls ejbLoad() for the bean only when:

- A client first references the EJB

- The EJB's transaction is rolled back

Restrictions for cache-between-transactions

The following restrictions apply to cache-between-transactions:

In a single-server deployment, enable cache-between-transactions only with Exclusive, Optimistic and Read-Only concurrency strategies. You cannot use cache-between transactions with a Database concurrency strategy.

In a clustered deployment, enable cache-between-transactions only with Optimistic and Read-Only concurrency strategies. You cannot use cache-between-transactions with an Exclusive or Database Concurrency strategy.

EJBs in WebLogic Server Clusters

This section describes clustering support for EJBs.

Clustered Homes and EJBObjects

EJBs in a WebLogic Server cluster use modified versions of two key structures: the Home object and the EJB object. In a single-server (unclustered) environment, a client looks up an EJB through the EJB's home interface, which is backed on the server by a corresponding Home object. After referencing the bean, the client interacts with the bean's methods through the remote interface, which is backed on the server by an EJB object.

The following figure shows EJB behavior in a single server environment.

Figure 4-8 Single server behavior

Note: Failover of EJBs work only between a remote client and the EJB.

Clustered EJB Home Objects

All EJB types—stateless session, stateful session, and entity EJBs—can have cluster-aware home stubs. Whether or not a cluster-aware home stub is created is determined by the home-is-clusterable deployment element in weblogic-ejb-jar.xml.

When an EJB bean is deployed to a cluster, its home is bound into the cluster-wide naming service. Each server can bind an instance of the home under the same name. When a client looks up this home, it gets a replica-aware stub that has a reference to the home on each server that deployed the bean. When create() or find() is called, the replica-aware stub routes the call to one of the replicas. The home replica receives the find() results or creates an instance of the bean on this server.

The clustered home stub provides load balancing by distributing EJB lookup requests to available servers. It can also provide failover support for lookup requests, because it routes those requests to available servers when other servers have failed.

Clustered EJBObjects

In a WebLogic Server cluster, the server-side representation of the EJBObject can also be replaced by a replica-aware EJBObject stub. This stub maintains knowledge about all copies of the EJBObject that reside on servers in the cluster. The EJBObject stub can provide load balancing and failover for EJB method calls. For example, if a client invokes an EJB method call on a particular WebLogic Server and the server goes down, the EJBObject stub can failover the method call to another, running server.

Whether or not an EJB can use a replica-aware EJBObject stub depends on the type of EJB deployed and, for entity EJBs, the concurrency strategy selected at deployment time. For more information, see Clustering Support for Different Types of EJBs.

Clustering Support for Different Types of EJBs

These sections describe the clustering support for session and entity EJBs.

- Stateless Session EJBs in a Cluster

- Stateful Session EJBs in a Cluster

- Entity EJBs in a Cluster

Stateless Session EJBs in a Cluster

Stateless session EJBs can have both a cluster-aware home stub and a replica-aware EJBObject stub. By default, WebLogic Server provides failover services for EJB method calls, but only if a failure occurs between method calls. For example, failover is automatically supported if a failure occurs after a method completes, or if the method fails to connect to a server. When failures occur while an EJB method is in progress, WebLogic Server does not automatically fail over from one server to another.

This default behavior ensures that database updates within an EJB method are not "duplicated" due to a failover scenario. For example, if a client calls a method that increments a value in a datastore and WebLogic Server fails over to another server before the method completes, the datastore would be updated twice for the client's single method call.

If methods are written in such a way that repeated calls to the same method do not cause duplicate updates, the method is said to be "idempotent." For idempotent methods, WebLogic Server provides two weblogic-ejb-jar.xml deployment properties, one at the bean level and one at the method level.

At the bean level, if you set stateless-bean-methods-are-idempotent to "true", WebLogic Server assumes that the method is idempotent and will provide failover services for the EJB method, even if a failure occurs during a method call.

At the method level, you can use the idempotent-methods deployment property to accomplish the same thing:

>     <idempotent-methods>
>     	<method>
>     		<description>...</description>
>     		<ejb-name>...</ejb-name>
>     		<method-intf>...</method-intf>
>     		<method-name>...</method-name>
>     		<method-params>...</method-params>
>     	</method>
>     </idempotent-methods>

The following figure illustrates stateless session EJBs in a WebLogic Server clustered environment.

Figure 4-9 Stateless session EJBs in a clustered server environment

Stateful Session EJBs in a Cluster

To enable stateful session EJBs to use cluster-aware home stubs, set home-is-clusterable to "true." This provides failover and load balancing for stateful EJB lookups. Stateful session EJBs configured this way use replica-aware EJBObject stubs. For more information on in-memory replication for stateful session EJBs, see In-Memory Replication for Stateful Session EJBs.

Note: Load balancing and failover are discussed extensively in Using WebLogic Server Clusters. See these three sections: "EJB and RMI Objects", "Load Balancing for EJBs and RMI Objects" and "Replication and Failover for EJBs and RMIs".

In-Memory Replication for Stateful Session EJBs

The WebLogic Server EJB container supports clustering for stateful session EJBs. Whereas in WebLogic Server 5.1 only the EJBHome object is clustered for stateful session EJBs, the EJB container can also replicate the state of the EJB across clustered WebLogic Server instances.

Replication support for stateful session EJBs is transparent to clients of the EJB. When a stateful session EJB is deployed, WebLogic Server creates a cluster-aware EJBHome stub and a replica-aware EJBObject stub for the stateful session EJB. The EJBObject stub maintains a list of the primary WebLogic Server instances on which the EJB instance runs, as well as the name of a secondary WebLogic Server to use for replicating the bean's state.

Each time a client of the EJB commits a transaction that modifies the EJB's state, WebLogic Server replicates the bean's state to the secondary server instance. Replication of the bean's state occurs directly in memory, for best performance in a clustered environment.

Should the primary server instance fail, the client's next method invocation is automatically transferred to the EJB instance on the secondary server. The secondary server becomes the primary WebLogic Server for the EJB instance, and a new secondary server handles possible additional failovers. Should the EJB's secondary server fail, WebLogic Server enlists a new secondary server instance from the cluster.

Clients of a stateful session EJB are therefore guaranteed to have quick access to the latest committed state of the EJB, except under the special circumstances described in Limitations of In-Memory Replication. For more information on the use of replication groups, see Using Replication Groups.

Requirements and Configuration for In-Memory Replication

To replicate the state of a stateful session EJB in a WebLogic Server cluster, make sure that the cluster is homogeneous for the EJB class. In other words, deploy the same EJB class to every WebLogic Server instance in the cluster, using the same deployment descriptor. In-memory replication is not supported for heterogeneous clusters.

By default, WebLogic Server does not replicate the state of stateful session EJB instances in a cluster. This models the behavior released with WebLogic Server Version 6.0. To enable replication, set the replication-type deployment parameter in the weblogic-ejb-jar.xml deployment file to InMemory.

Figure 4-10 XML sample enabling replication

>     <stateful-session-clustering>
>     	...
>     	<replication-type>InMemory</replication-type>
>     </stateful-session-clustering>

Limitations of In-Memory Replication

By replicating the state of a stateful session EJB, clients are generally guaranteed to have the last committed state of the EJB, even if the primary WebLogic Server instance fails. However, in the following rare failover scenarios, the last committed state may not be available:

- A client commits a transaction involving a stateful EJB, but the primary WebLogic Server fails before the EJB's state is replicated. In this case, the client's next method invocation works against the previous committed state.

- A client creates an instance of a stateful session EJB and commits an initial transaction, but the primary WebLogic Server fails before the EJB's initial state can be replicated. The client's next method invocation fails to locate the bean instance, because the initial state could not be replicated. The client needs to recreate the EJB instance, using the clustered EJBHome stub, and restart the transaction.

- Both the primary and secondary servers fail. The client needs to recreate the EJB instance and restart the transaction.

Entity EJBs in a Cluster

As with all EJBs, entity EJBs can utilize cluster-aware home stubs once you set home-is-clusterable to "true."

The behavior of the EJBObject stub depends on the concurrency-strategydeployment element in weblogic-ejb-jar.xml. concurrency-strategy can be set to Read-Write or Read-Only. The default value is Read-Write.

Fore details, see:

- Read-Only Entity EJBs in a Cluster

- Read-Write Entity EJBs in a Cluster

Read-Only Entity EJBs in a Cluster

When a home finds or creates a read-only entity bean, it returns a replica-aware an EJBObject stub. This stub load balances on every call but does not automatically fail over in the event of a recoverable call failure. Read-only beans are also cached on every server to avoid database reads.

Read-Write Entity EJBs in a Cluster

When a home finds or creates a read-write entity bean, it obtains an instance on the local server and returns an EJBObject stub pinned to that server. Load balancing and failover occur only at the home level. Because it is possible for multiple instances of the entity bean to exist in the cluster, each instance must read from the database before each transaction and write on each commit.

read-write entity EJBs in a cluster behave similarly to entity EJBs in a non-clustered system, in that:

- Multiple clients can use the bean in transactions.

- ejbLoad() is always called at the beginning of each transaction when cache-between-transactions is set to false.

- ejbStore() behavior is governed by the rules described in ejbLoad() and ejbStore() Behavior for Entity EJBs

Figure 4-11 shows read-write entity EJBs in a WebLogic Server clustered environment. The three arrows on Home Stub point to all three servers and show multiple client access.

Figure 4-11 Read-write entity EJBs in a clustered server environment

Note: In the preceding figure, the set of three arrows for both home stubs refers to the EJBHome on each server.

read-write entity EJBs support automatic failover on a safe exception, if home-is-clusterable is set to true. For example, failover is automatically supported if there is a failure after a method completes, or if the method fails to connect to a server.

Cluster Address

When you configure a cluster, you supply a cluster address that identifies the Managed Servers in the cluster. The cluster address is used in entity and stateless beans to construct the host name portion of URLs. If the cluster address is not set, EJB handles may not work properly. For more information on cluster addresses, see Using WebLogic Server Clusters.

Transaction Management

The following sections provide information on how the EJB container supports transaction management services. They describe EJBs in several transaction scenarios. EJBs that engage in distributed transactions (transactions that make updates in multiple datastores) guarantee that all branches of the transaction commit or roll back as a logical unit.

The current version of WebLogic Server supports Java Transaction API (JTA), which you can use to implement distributed transactional applications.

Also, two-phase commit is supported for both 1.1 and 2.0 EJBs. The two-phase commit protocol is a method of coordinating a single transaction across two or more resource managers. It guarantees data integrity by ensuring that transactional updates are committed in all participating databases, or are fully rolled back out of all the databases, reverting to the state prior to the start of the transaction.

Transaction Management Responsibilities

Session EJBs can rely on their own code, their client's code, or the WebLogic Server container to define transaction boundaries. EJBs can use container- or client-demarcated transaction boundaries, but they cannot define their own transaction boundaries unless they observe certain restrictions.

- In bean-managed transactions, the EJB' code manages the transaction demarcation. If bean- or client-managed transactions are required, you must provide the java code and use the javax.transaction.UserTransaction interface. The EJB or client can then access a UserTransaction object through JNDI and specify transaction boundaries with explicit calls to tx.begin(), tx.commit(), tx.rollback(). See Using javax.transaction.UserTransaction for more information on defining transaction boundaries.

- In container-managed transactions, the WebLogic Server EJB container manages the transaction demarcation. For EJBs that use container-managed transactions, you can use several deployment elements to control the transactional requirements for individual EJB methods. For more information about the deployment descriptors, see Programming WebLogic EJB.

Note: If the EJB provider does not specify a transaction attribute for a method in the ejb-jar.xml file, WebLogic Server uses the supports attribute by default.

The sequence of transaction events differs between container-managed and bean-managed transactions.

Using javax.transaction.UserTransaction

To define transaction boundaries in EJB or client code, you must obtain a UserTransaction object and begin a transaction before you obtain a Java Transaction Service (JTS) or JDBC database connection. To obtain the UserTransaction object, use this command:

ctx.lookup("javax.transaction.UserTransaction");

If you start a transaction after obtaining a database connection, the connection has no relationship to the new transaction, and there are no semantics to "enlist" the connection in a subsequent transaction context. If a JTS connection is not associated with a transaction context, it operates similarly to a standard JDBC connection that has autocommit equal to true, and updates are automatically committed to the datastore.

Once you create a database connection within a transaction context, that connection becomes "reserved" until the transaction either commits or rolls back. To maintain performance and throughput for your applications, always ensure that your transaction completes quickly, so that the database connection can be released and made available to other client requests. See Preserving Transaction Resources for more information.

Note: You can associate only a single database connection with an active transaction context.

Restriction for Container-Managed EJBs

You cannot use the javax.transaction.UserTransaction method within an EJB that uses container-managed transactions.

Transaction Isolation Levels

The method for setting the transaction isolation level differs according to whether your application uses bean-managed or container-managed transaction demarcation. The following sections examine each of these scenarios.

Setting Bean-Managed Transaction Isolation Levels

You set the isolation level for bean-managed transactions in the EJB's java code. When the application runs, the transaction is explicitly started. Allowable isolation levels are defined in transaction-isolation.

Note: The Oracle-only isolation level values—TRANSACTION_READ_COMMITTED_FOR_UPDATE and TRANSACTION_READ_COMMITTED_FOR_UPDATE_NO_WAIT cannot be set for a bean-managed transaction.

See Figure 4-12 for a code sample.

Figure 4-12 Sample Code Setting Transaction Isolation Level

>     import javax.transaction.Transaction;
>     import java.sql.Connection
>     import weblogic.transaction.TxHelper:
>     import weblogic.transaction.Transaction;
>     import weblogic.transaction.TxConstants;

>     User Transaction tx = (UserTransaction)

>     ctx.lookup("javax.transaction.UserTransaction");

>     //Begin user transaction

>     	tx.begin();

>     //Set transaction isolation level to TRANSACTION_READ_COMMITED

>     Transaction tx = TxHelper.getTransaction();
>     	tx.setProperty (TxConstants.ISOLATION_LEVEL, new Integer
>     	 (Connection.TRANSACTION_READ_COMMITED));

>     //perform transaction work

>     	tx.commit();

Setting Container-Managed Transaction Isolation Levels

You set the isolation level for container-managed transactions in the isolation-level sub-element of the transaction-isolation element of the weblogic-ejb-jar.xml deployment file. WebLogic Server passes this value to the underlying database. The behavior of the transaction depends both on the EJB's isolation level setting and the concurrency control of the underlying persistent store. For more information on setting container-managed transaction isolation levels, see Programming WebLogic JTA.

Limitations of TransactionSerializable

Many datastores provide limited support for detecting serialization problems, even for a single user connection. Therefore, even if you set transaction-level to TransactionSerializable setting for an EJB, you may receive exceptions or rollbacks in the EJB client if contention occurs between clients for the same rows. To prevent these problems, make sure that the code in your client application catches and examines the SQL exceptions, and that you take the appropriate action to resolve the exceptions, such as restarting the transaction.

WebLogic Server provides special isolation-level settings designed to prevent this problem with Oracle databases, as described in Special Note for Oracle Databases.

For other database vendors, refer to your database documentation for more details about isolation level support.

Special Note for Oracle Databases

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 Server provides special isolation-level settings to prevent this. For more information, see isolation-level.

Distributing Transactions Across Multiple EJBs

WebLogic Server does support transactions that are distributed over multiple datasources; a single database transaction can span multiple EJBs on multiple servers. You can explicitly enable support for these types of transactions by starting a transaction and invoking several EJBs. Or, a single EJB can invoke other EJBs that implicitly work within the same transaction context. The following sections describe these scenarios.

Calling Multiple EJBs from a Single Transaction Context

In the following code fragment, a client application obtains a UserTransaction object and uses it to begin and commit a transaction. The client invokes two EJBs within the context of the transaction. The transaction attribute for each EJB is set to Required:

Figure 4-13 Beginning and committing a transaction

>     import javax.transaction.*;
>     ...
>     u = (UserTransaction) jndiContext.lookup("javax.transaction.UserTransaction");
>     u.begin();
>     account1.withdraw(100);
>     account2.deposit(100);
>     u.commit();
>     ...

In the above code fragment, updates performed by the "account1" and "account2" EJBs occur within the context of a single UserTransaction. The EJBs commit or roll back as a logical unit. This is true regardless of whether "account1" and "account2" reside on the same WebLogic Server, multiple WebLogic Servers, or a WebLogic Server cluster.

The only requirement for wrapping EJB calls in this manner is that both "account1" and "account2" must support the client transaction. The beans' trans-attribute element must be set to Required, Supports, or Mandatory.

Encapsulating a Multi-Operation Transaction

You can also use a "wrapper" EJB that encapsulates a transaction. The client calls the wrapper EJB to perform an action such as a bank transfer. The wrapper EJB responds by starting a new transaction and invoking one or more EJBs to do the work of the transaction.

The "wrapper" EJB can explicitly obtain a transaction context before invoking other EJBs, or WebLogic Server can automatically create a new transaction context, if the EJB's trans-attribute element is set to Required or RequiresNew. The trans-attribute element is set in the ejb-jar.xml file. All EJBs invoked by the wrapper EJB must be able to support the transaction context (their trans-attribute elements must be set to Required, Supports, or Mandatory).

Distributing Transactions Across EJBs in a WebLogic Server Cluster

WebLogic Server provides additional transaction performance benefits for EJBs that reside in a WebLogic Server cluster. When a single transaction utilizes multiple EJBs, WebLogic Server attempts to use EJB instances from a single WebLogic Server instance, rather than using EJBs from different servers. This approach minimizes network traffic for the transaction.

In some cases, a transaction can use EJBs that reside on multiple WebLogic Server instances in a cluster. This can occur in heterogeneous clusters, where all EJBs have not been deployed to all WebLogic Server instances. In these cases, WebLogic Server uses a multitier connection to access the datastore, rather than multiple direct connections. This approach uses fewer resources, and yields better performance for the transaction.

However, for best performance, the cluster should be homogeneous — all EJBs should reside on all available WebLogic Server instances.

Database Insert Support

WebLogic Server allows you to control when and how the EJB container inserts newly created beans into the database.You specify your preference by setting the delay-database-insert-until deployment descriptor element in the weblogic-cmp-rdbms-jar.xml file. This element allows you to choose:

- To delay the database insert until after the EJB Container performs either an ejbCreate or ejbPostCreate, as described in the following section.

- To insert multiple entries into the database in one SQL statement, as described in Bulk Insert.

The allowed values for the delay-database-insert-until element are:

- ejbCreate—This method performs a database insert immediately after ejbCreate.

- ejbPostCreate—This method performs an insert immediately after ejbPostCreate (default).

- commit—performs a bulk insert when the transaction commits

  Figure 4-14 Sample xml specifying delay-database-insert-until

>     <delay-database-insert-until>ejbPostCreate</delay-database-insert-until> -->

Delay-Database-Insert-Until

By default, the database insert occurs after the client calls the ejbPostCreate method. The EJB container delays inserting the new bean when you specify either the ejbCreate or ejbPostCreate options for the delay-database-insert-until element in the weblogic-cmp-rdbms-jar.xml file. Setting either of these options specifies the precise time at which the EJB Container inserts a new bean that uses RDBMS CMP into the database.

You must specify that the EJB Container delay the database insert until after ejbPostCreate when a cmr-field is mapped to a foreign-key column that does not allow null values. In this case, set the cmr-field to a non-null value in ejbPostCreate before the bean is inserted into the database.

Note: You may not set the cmr-fields during a ejbCreate method call, before the primary key of the bean is known.

BEA recommends that you specify the delay the database insert until after ejbPostCreate if the ejbPostCreate method modifies the bean's persistent field. Doing so yields better performance by avoiding an unnecessary store operation.

For maximum flexibility, avoid creating related beans in their ejbPostCreate method. Creating these additional instances may make delaying the database insert impossible if database constraints prevent related beans from referring to a bean that has not yet been created.

Note: In a one-to-one relationship, if the parent bean's primary key is embedded in the child bean's CMR field, when the EJB container creates the beans, it will not check if the parent bean has children, for performance reasons. To avoid a duplicationKeyException database exception, you must set the foreign key constraint on the child table in the database.

Bulk Insert

Bulk insert support increases the performance of container-managed persistence (CMP) bean creation by enabling the EJB container to perform multiple database inserts for CMP beans in one SQL statement. This feature allows the container to avoid making multiple database inserts.

The EJB container performs bulk database inserts when you specify the commit option for the delay-database-insert-until element in the weblogic-cmp-rdbms-jar.xml file.

When using bulk insert, you must set the boundary for the transaction as bulk insert only applies to the inserts between transaction begin and transaction commit.

Note: Bulk insert only works with drivers that support the addBatch() and executeBatch() methods. For example, the Oracle thin driver supports these methods but the WebLogic Oracle JDBC driver does not.

The two limitations on using bulk insert are:

The total number of entries you create in a single bulk insert cannot exceed the max-beans-in-cache setting, which is specified in the weblogic-ejb-jar.xml file. See max-beans-in-cache for more information on this element.

If you set the dbms-column-type element in the weblogic-cmp-rdbms-jar.xml file to either OracleBlob or OracleClob, bulk insert automatically turns off because you will not save much time if a Blob or Clob column exist in the database table. In this case, WebLogic Server performs one insert per bean, which is the default behavior.

Resource Factories

The following sections provide information on how the EJB container supports resource services. In WebLogic Server, EJBs can access JDBC connection pools by directly instantiating a JDBC pool driver. However, it is recommended that you instead bind a JDBC datasource resource into the WebLogic Server JNDI tree as a resource factory.

Using resource factories enables the EJB to map a resource factory reference in the EJB deployment descriptor to an available resource factory in a running WebLogic Server. Although the resource factory reference must define the type of resource factory to use, the actual name of the resource is not specified until the bean is deployed.

The following sections explain how to bind JDBC datasource and URL resources to JNDI names in WebLogic Server.

Note: WebLogic Server also supports JMS connection factories.

Setting Up JDBC Data Source Factories

Follow these steps to bind a javax.sql.DataSource resource factory to a JNDI name in WebLogic Server. Note that you can set up either a transactional or non-transactional JDBC datasource as necessary.

With a non-transactional data source, the JDBC connection operates in auto commit mode, committing each insert and update operation to the database immediately, rather than as part of a container-managed transaction.

With a transactional data source, multiple insert and update operations in a method can be submitted as a single, container-managed transaction that either commits or rolls back as a logical unit.

Note: Entity beans that use container-managed persistence should always use a transactional data source, rather than a non-transactional data source, to preserve data consistency.

To create a JDBC data source factory:

1. Set up a JDBC connection pool in the Administration Console. See Managing JDBC Connectivity in the Administration Guide for more information.

2. Start WebLogic Server.

3. Start WebLogic Server Administration Console.

4. In the left pane of the Console, click the Services node and expand JDBC.

5. Select JDBC Data Source Factory and click the Configure a New JDBC Data Source Factory option in the right pane.

6. Enter values in the Name, User Name, URL, Driver Class Name, and Factory Name, attribute fields.

7. Enter any connection properties in the Properties attribute field.

   1. For non-transactional JDBC datasources, enter:

      >     weblogic.jdbc.DataSource.jndi_name=pool_name

   where jndi_name is the full WebLogic Server JNDI name to bind to the datasource and pool_name is the name of the WebLogic Server connection pool you created in step 1.

   1. For transactional JDBC datasources, select Tx Data Sources from the left pane of the Administration Console, click Configure a New JDBC Tx Data Source in the right pane, and enter:

      >     weblogic.jdbc.TXDataSource.jndi_name=pool_name

   where jndi_name is the full WebLogic Server JNDI name to bind to the transactional datasource and pool_name is the name of the WebLogic Server connection pool you created in step 1.

   For more information on configuring transactional and non-transactional data sources, see Configure a JDBC Data Source.

8. Click Create to create the JDBC Data Source Factory. The new Data Source Factory is added under the JDBC Data source Node in the left pane.

9. Click Apply to save the changes.

10. Bind the JNDI name of the datasource to the EJB's local JNDI environment by doing one of the following:

    - Map an existing EJB resource factory reference to the JNDI name.

    - Directly edit the resource-description element in the weblogic.ejb-jar.xml deployment file. See Specifying and Editing the EJB Deployment Descriptors for instructions on editing deployment descriptors.

Setting Up URL Connection Factories

To set up a URL connection factory in WebLogic Server, bind a URL string to a JNDI name using these instructions:

1. In a text editor, open the config.xml file for the instance of the WebLogic Server you are using and set the URLResource attribute for the following config.xml elements:

   - WebServer

   - VirtualHost:

2. Set the URLResource attribute for the WebServer element using the following syntax:

   >     <WebServer URLResource="weblogic.httpd.url.testURL=http:// localhost:7701/testfile.txt" DefaultWebApp="default-tests"/>

3. Set the URLResource attribute for the VirtualHost element, when virtual hosting is required, using the following syntax:

   >     <VirtualHostName=guestserver" targets="myserver,test_web_server "URLResource="weblogic.httpd.url.testURL=http:// localhost:7701/testfile.txt" VirtualHostNames="guest.com"/>

4. Save the changes in the config.xml file and reboot WebLogic Server.