Entity Bean Features


The next set of WebLogic Server-specific features covers the capabilities related to entity beans. There are a large number of entity bean capabilities provided by WebLogic Server; far more than any other type of EJB component. In a sense, this reflects the complexity of the problem entity beans are being asked to solve and the need for features above and beyond the J2EE specification to create enterprise-class applications. There are many possible strategies for achieving good performance with proper transactional controls and concurrency. No single strategy is best is all situations, and the EJB container relies on the application developer to configure entity-bean persistence properly for best performance.

This section covers strategies and best practices in four major areas: concurrency, caching, tuning queries and persistence operations, and advanced CMP features. You should be aware of all possible strategies and their implications before choosing a strategy for your entity bean-based J2EE application.

Concurrency Strategies

The basic load-and-store cycle used to read and write entity-bean data on a per- transaction basis is sufficient, in theory, to ensure that clients always interact with a bean containing the latest data in the database. This simplistic approach might be sufficient for small applications with few users and limited performance requirements, but it fails to meet the needs of a true enterprise-class architecture for two reasons:

  • No caching of bean data. In this simplistic approach, every transaction with an entity bean involves a database operation to retrieve bean data from the persistent store. You saw this behavior in the simple PersonBMPBean example application earlier. The bean-instance caching defined by the EJB specification does not cache the contents of the beans, only the instance created in the pool. You therefore need some facility for safely caching bean data to improve performance where appropriate.

  • No concurrency support. The simplistic load-and-store cycle does not specify how to handle multiple clients interacting with the same entity bean during this life cycle. To make matters worse , if the application is clustered across multiple servers, the clients accessing the beans may be using different EJB containers running on different JVMs on different machines. Coordinating concurrent access to bean data across multiple containers is also a requirement for enterprise-class systems.

WebLogic Server provides a robust set of caching and concurrency options to address these two limitations. You should recognize that caching of data and controlling concurrent access to data are strongly interrelated. WebLogic Server combines approaches for both sides of the problem in a set of concurrency strategies :

  • Exclusive concurrency strategy , or exclusive locking , addresses the concurrency side of the problem by using in-memory locking to serialize access to specific bean instances in an EJB container. Caching can be configured using the cache-between-transactions feature, described later in this chapter, in a nonclustered environment.

  • Database concurrency strategy , or database locking , addresses the concurrency side of the problem by relying on the underlying database technology to reject changes made by two simultaneous transactions. Caching data between transactions is not possible with this strategy.

  • Read-only concurrency strategy is more of a caching solution than a concurrency solution. Bean data is kept in memory and loaded from the database as a result of time-out or explicit invalidation . Concurrent access to bean data is allowed through the creation of multiple beans.

  • Optimistic concurrency strategy , or optimistic locking , uses the classic client/server approach of ensuring that the underlying database rows have not been updated by any other client during the life cycle of the bean. Caching is possible using the cache-between-transactions feature in both clustered and nonclustered environments. Only CMP entity beans may use this strategy.

We ll discuss each of these concurrency strategies in detail in the sections that follow.

The desired concurrency strategy is defined on a per-bean basis in the weblogic-ejb-jar.xml descriptor file in the entity-cache element in the entity descriptor:

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

The default concurrency strategy in WebLogic Server 6. x and later is database concurrency. Prior versions used exclusive concurrency by default.

Exclusive Concurrency Strategy

The exclusive concurrency strategy uses in-memory locking to serialize access to bean instances in an EJB container. When a client enlists a specific entity bean instance in a transaction by calling a method on the bean interface, the EJB container creates an exclusive lock on that bean instance held for the duration of the transaction. Other clients attempting to enlist the same bean in a transaction are forced to wait for the first transaction to complete before acquiring the lock on the instance. Because the first client s lock is not released until the transaction completes and modified data is flushed to the database, the next client will always see the latest committed data when the container loads the data on its behalf .

Table 6.3 presents a simplified example of this process for two clients attempting to access the same entity bean at the same time. Clearly the activity becomes more complex if additional EJB components are involved in the transaction, but the example represents the primary activities in the process.

Table 6.3:  Exclusive Concurrency Example

Client #1 Thread Activity

Client #2 Thread Activity

The client acquires a reference to bean 101.

The client acquires a reference to bean 101.

The client invokes a method on the bean interface.

 

The EJB container intercepts the request, starts the transaction, enlists bean 101 in the transaction, and places an exclusive lock on bean 101 in the lock manager.

 

The EJB container loads the data from the database into the bean instance.

The client invokes a method on the bean interface

The EJB container passes the request to a method on the bean instance.

The EJB container intercepts the request, starts the transaction, and blocks the thread, waiting to obtain an exclusive lock on bean 101.

The bean instance processes the request and returns.

The thread is blocked.

The EJB container saves the bean instance s state to the database.

The thread is blocked.

The EJB container commits the transaction and removes the exclusive lock on bean 101.

The thread is blocked.

The results are returned to the client.

The EJB container enlists bean 101 in the transaction and places an exclusive lock on bean 101 in the lock manager.

 

The EJB container loads the data from the database into the bean instance.

 

The EJB container passes the request to a method on the bean instance.

 

The bean instance processes the request and returns.

 

The EJB container saves the bean instance s state to the database.

 

The EJB container commits the transaction and removes the exclusive lock on bean 101.

 

The results are returned to the client.

There are a number of problems with this concurrency strategy when applied to realistic, enterprise-class applications:

  • Most enterprise-class applications are deployed in a cluster, and each server instance in the cluster will deploy the EJB components in a separate EJB container. Because exclusive locking is performed by each EJB container and is local to that container only, there is no concurrency control across servers in the cluster. In other words, if two clients were talking to bean instances representing the same business object on two different servers, the second client would not be blocked by the first client. In effect, clients going to different servers use database concurrency while clients going to the same server use exclusive concurrency.

  • The EJB container does not discriminate between read and write operations for locking, so clients wishing to read data from the bean are blocked in the same way as clients performing updates. This can produce significant response-time degradation if contention occurs for the same entity beans.

  • Exclusive locking brings with it the problem of potential deadlocks. Deadlocks occur when two clients access a set of entity beans in a different order, such that each client thread is blocked waiting for the other client thread to release the lock it needs to proceed. Such deadlocks are difficult to avoid unless you take extreme care to ensure that all access to multiple entity beans proceeds in a consistent order in every component of the application.

Some of these issues are the result of requiring the EJB container to maintain strong transactional and isolation controls, or ACID properties, for the underlying data. The container cannot, for example, allow read access to a bean instance involved in another transaction without violating basic isolation rules.

The exclusive concurrency strategy is no longer the default strategy in WebLogic Server. Use this strategy sparingly, if at all, and remember that the locking is on a per-container basis.

Best Practice  

Avoid exclusive concurrency unless synchronizing access to the underlying data source is critical to the correct operation of the system. Recognize that clustered environments generally defeat exclusive locking because of its per-container implementation. Be aware of potential deadlocks when using exclusive locking, and control the order of lock acquisition throughout your application to avoid deadlocks.

Configuring the exclusive concurrency strategy requires the following element in the entity-descriptor for the entity bean:

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

There are no other options or elements associated with the exclusive concurrency strategy. Note that this strategy may be combined with the cache between transactions caching strategy described later in this chapter in a single server environment.

Database Concurrency Strategy

The database concurrency strategy relies on the underlying database technology to reject changes made by two simultaneous transactions. Rather than enforce exclusive access to a given bean, the container gives all clients their own copies of the entity bean at the start of their individual transactions and allows the database to catch and reject attempts to access the underlying data in ways that violate the isolation level in use. Essentially , the database concurrency strategy in its simplest form represents no concurrency control at all in the EJB container.

If multiple clients obtain references to the same bean and call only get methods, as opposed to set methods , this concurrency strategy has no effect on the life cycle of the bean instances. Each bean is loaded, processes the get requests , and is removed from the cache. Because the CMP logic is smart enough to avoid executing an update statement when only get methods are called, no database updates occur and no concurrency issues exist. Each bean life cycle is independent.

If multiple clients obtain references to the same bean and do call set methods on the bean, the final database-update step in the bean life cycle will be performed by one client before the others, and the database locking will prevent subsequent commits from succeeding under most conditions. Specific database technologies and isolation levels affect this behavior, of course, but Table 6.4 illustrates the normal case in more detail.

Table 6.4:  Database Concurrency Example

CLIENT #1 THREAD ACTIVITY

CLIENT #2 THREAD ACTIVITY

The client acquires a reference to bean 101.

The client acquires a reference to bean 101.

The client invokes a method on the bean interface.

 

The EJB container intercepts the request, starts the transaction, instantiates bean 101 in the cache, and enlists bean 101 in the transaction.

 

The EJB container loads the data from the database into the bean instance.

The client invokes a method on the bean interface.

The EJB container passes the request to a method on the bean instance.

The EJB container intercepts the request, starts the transaction, instantiates bean 101 in the cache, and enlists bean 101 in the transaction.

The bean instance processes the request and returns.

The EJB container loads the data from the database into the bean instance.

The EJB container saves the bean instance s state to the database.

The EJB container passes the request to the method on the bean instance.

The EJB container commits the transaction.

The bean instance processes the request and returns.

The results are returned to the client.

The EJB container saves the bean instance s state to the database.

 

The EJB container attempts to commit the transaction. The database raises an exception because of the previous commit by Client #1.

 

The database exception is returned to the client.

Because Client #1 performs the commit before Client #2, the transaction in the Client #2 thread is doomed to fail during either the database update step or the final transaction commit step. Where it fails depends on the specific database technology.

The database concurrency strategy has two significant advantages over the exclusive strategy:

  • No locking or synchronization is performed by the EJB container. This eliminates the potential for deadlocks in the EJB container and improves performance considerably for applications that suffer from contention related to certain entity beans.

  • The database concurrency strategy works in a cluster because it relies on the RDBMS, a shared service, for concurrency control, rather than on the individual EJB containers.

There are three big disadvantages with the database concurrency strategy, however:

  • Transactions may fail during the database update or commit step in the bean life cycle, raising a database-related exception to the client. Client code must catch this exception and decide if it is safe to retry the entire transaction again. The entire transaction rolls back, not just the portion related to the entity bean that caused the exception.

  • WebLogic Server does not allow the use of the cache-between-transactions feature with this concurrency strategy. As you will see when this feature is covered later, cache-between-transactions eliminates the need to reload the data from the database for a bean found in the cache, potentially representing a large performance gain. Because the database concurrency strategy always provides and loads a new bean for each client, it is incompatible with this caching feature.

  • You are essentially moving any potential deadlocks from the EJB container down to the database.

Despite these disadvantages, database concurrency represents a solid starting point and is preferred over exclusive concurrency in most applications.

Best Practice  

The database concurrency strategy is preferred over the exclusive strategy in most applications, but it suffers from the lack of support for caching data between transactions.

The database concurrency strategy is the default in WebLogic 6. x and later, so failing to explicitly set the caching strategy on a bean causes WebLogic Server to use database concurrency. You may also declare the strategy explicitly using this element:

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

Read-Only Concurrency Strategy

The read-only concurrency strategy in WebLogic 7. x and later is an improved version of the standard read-only entity beans available in WebLogic 5. x and 6. x . This improved read-only concurrency strategy provides a mechanism for the long- term caching of entity bean data in the EJB container, while eliminating the previous requirement for exclusive access to the cached bean instance.

When using this strategy, the container will populate a particular bean instance the first time it is referenced by a client by reading the bean s state from the database. Subject to max-beans-in-cache limitations, this bean instance then remains in memory indefinitely and is used by the container during subsequent invocations by new clients. In previous versions of WebLogic Server, this cached bean had to be accessed by clients using an exclusive locking scheme, creating the potential for deadlocks and performance bottlenecks. WebLogic Server 7. x and later changes the default behavior of read-only beans to avoid this exclusive locking by copying bean data from the cached bean instance to a separate instance for each client request.

The EJB container never tries to save the bean s state at the end of transactions involving read-only beans, so no changes can be made to the persistent data through these beans.

An entity bean is declared to be read-only by setting the concurrency-strategy element to ReadOnly . Beans with this setting use the new caching mechanism that avoids exclusive locks on the cached bean data. To configure beans to use exclusive locking on the cached bean data, thereby simulating the behavior of read-only beans in WebLogic 5. x and 6. x , use the ReadOnlyExclusive concurrency strategy.

The read-timeout-seconds element may also be included with both ReadOnly and ReadOnlyExclusive beans:

 <entity-cache>   ...   <  read-timeout-seconds  >  600  <  /read-timeout-seconds  >   <concurrency-strategy>ReadOnly</concurrency-strategy> </entity-cache> 

This element adds another check during each method invocation on the cached bean to verify that the cached data has not expired . If the data is older than the time-out setting, the container reloads the bean s state from the persistent store to refresh the cache. The method invocation that caused the refresh, and all subsequent calls by clients, will receive bean instances containing a copy of the updated data. The default value of read-timeout-seconds is 0, meaning that no time-out checks will occur and the bean s state will be loaded from the persistent store only during initial bean creation and after explicit invalidation, a topic covered later in this chapter.

It is also possible to configure entire groups of entity beans to have the ReadOnly or ReadOnlyExclusive concurrency strategy using the weblogic-application.xml descriptor file. This capability is part of the combined-caching-support feature introduced in WebLogic Server 7.0, which will be discussed later in this chapter.

Optimistic Concurrency Strategy

The optimistic concurrency strategy enforces concurrency using the classic client/server approach of ensuring that the underlying database rows have not been updated by any other client during the transaction. This strategy is available only for CMP entity beans.

Optimistic locking schemes take advantage of the fact that most access to bean data is for read purposes. Each client thread is given its own copy of the entity bean, much like the database strategy, and checks are performed during the final database update to ensure that no changes have occurred in the database during the bean life cycle. We ll discuss the specific types of checks that can be performed and the techniques used by WebLogic Server to ensure concurrency in a moment.

Table 6.5 presents a simple example for two clients accessing and modifying the same bean.

Table 6.5:  Optimistic Concurrency Example

CLIENT #1 THREAD ACTIVITY

CLIENT #2 THREAD ACTIVITY

The client acquires a reference to bean 101.

The client acquires a reference to bean 101.

The client invokes a method on the bean interface.

 

The EJB container intercepts the request, starts the transaction, instantiates bean 101 in the cache, and enlists bean 101 in the transaction.

 

The EJB container loads the data from the database into the bean instance and saves key attribute values in the bean for concurrency checks in the database update step.

The client invokes a method on the bean interface.

The EJB container passes the request to a method on the bean instance.

The EJB container intercepts the request, starts the transaction, instantiates bean101 in the cache, and enlists bean 101 in the transaction.

The bean instance processes the request and returns.

The EJB container loads the data from the database into the bean instance and saves key attribute values in the bean for concurrency checks in the database update step.

The EJB container performs the database update using the previous key attribute values in the WHERE clause, verifies that the update modified the row, and completes successfully.

The EJB container passes the request to a method on the bean instance.

The EJB container commits the transaction.

The bean instance processes the request and returns.

The results are returned to the client.

The EJB container performs the database update using the previous key attribute values in the WHERE clause, senses that the update didn t modify the database, rolls back the transaction, and raises an exception.

 

An OptimisticConcurrency Exception is returned to the client.

The optimistic concurrency strategy ensures that the row in the database has not changed during the life cycle of the bean. This is accomplished in WebLogic Server by saving, in the entity bean instance, the values of specific fields as they existed during the database read invocation. These saved values are then used in database update operations to verify that the database row has not changed by including them in the WHERE clause of the SQL UPDATE statement.

WebLogic Server supports four different techniques for checking the saved values in the bean instance against the current contents of the database row:

  • Check all fields read during transaction , which requires that all of the fields read from the database during the transaction still have their original values in the database row.

  • Check fields modified during transaction , which requires that any fields being modified by the UPDATE statement itself still have their original values in the database row.

  • Check a version column , which requires that a specific numeric column in the mapped table still contains the value it did during the database read.

  • Check a timestamp column , which requires that a specific timestamp column in the mapped table still contains the value it did during the database read.

The Optimistic strategy is declared in the weblogic-ejb-jar.xml file:

 <entity-cache>   ...   <concurrency-strategy>  Optimistic  </concurrency-strategy> </entity-cache> 

The technique used to validate the bean values during the database update process is defined in the CMP descriptor file, weblogic-cmp-rdbms-jar.xml , in a verify- columns element inside the table mapping section:

 <weblogic-rdbms-jar>   <weblogic-rdbms-bean>     <ejb-name>PersonCMPEJB</ejb-name>     <data-source-name>MasteringDataSource</data-source-name>     <table-map>       <table-name>PERSON</table-name>       <field-map>         <cmp-field>id</cmp-field>         <dbms-column>ID</dbms-column>       </field-map>       ...       <field-map>         <cmp-field>lastName</cmp-field>         <dbms-column>LASTNAME</dbms-column>       </field-map>   <  verify-columns  >  Modified  <  /verify-columns  >     </table-map>   </weblogic-rdbms-bean> </weblogic-rdbms-jar> 

Valid values for verify-columns are Read , Modified , Version , and Timestamp .

The Read and Modified techniques require no other elements in the descriptor because the container will construct the WHERE clause used in the row update based on columns read or modified as appropriate. The Version and Timestamp techniques require an additional optimistic-column element in the table mapping section defining the table column used for these techniques:

 <table-map>   <table-name>PERSON</table-name>   ...   <verify-columns>Timestamp</verify-columns>   <  optimistic-column  >  LAST_MODIFIED  <  /optimistic-column  > </table-map> 

The column used for Version or Timestamp checking may be included in the container-managed fields for the CMP bean, but this is not required. You may not call the set method for this field.

Best Practice  

The Version and Timestamp techniques are the most direct implementations of optimistic concurrency and are recommended for most applications. The Read and Modified techniques work well if there are no timestamp or version columns available in the table, but they may create long WHERE clauses that must be parsed and evaluated by the underlying database system for every update, hurting performance.

Regardless of the technique you use, WebLogic Server includes appropriate additional criteria on the WHERE clause in the internal database update operation to enforce concurrency. For example, if the PersonCMPBean defined earlier in this chapter used optimistic locking with a Modified technique, and the firstName and lastName attributes were modified during the bean life cycle, the executed SQL statement would be as follows :

 UPDATE PERSON SET FIRSTNAME = ? , LASTNAME = ?               WHERE ID = ? AND FIRSTNAME = ? AND LASTNAME = ? 

If this statement fails to update a row in the database, the EJB container assumes another client has either deleted the row or another client or process changed one of the modified fields. In either case, there is a concurrency problem, and the container throws an OptimisticConcurrencyException :

 weblogic.ejb.OptimisticConcurrencyException:  Optimistic concurrency violation. Instance of bean 


Mastering BEA WebLogic Server. Best Practices for Building and Deploying J2EE Applications
Mastering BEA WebLogic Server: Best Practices for Building and Deploying J2EE Applications
ISBN: 047128128X
EAN: 2147483647
Year: 2003
Pages: 125

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net