Skip to main content

IBM WebSphere Developer Technical Journal: Understanding WebSphere Application Server EJB access intents

Mattias Persson (mpersson@uk.ibm.com), Staff Software Engineer, IBM
Mattias Persson works in the Java Technology Centre, Hursley Park IBM in the UK. He is a member of Java Performance Team and has a personal focus on the measurement and optimization of application server environments. He is a Certified Enterprise Architect for J2EE and received an MSc in Computer Science from Vaxjo University, Sweden, in 2002. He then joined IBM as a graduate.

Summary:  WebSphere® Application Server defines a set of extensions called access intent policies that govern access to entity beans. Understanding how this feature works can be an important factor when tuning the performance of an EJB™ application. This article also shows how to configure access intent within WebSphere Studio Application Developer V5.1.1.

Date:  17 Jun 2004
Level:  Intermediate
Activity:  563 views

Get the products and tools used in this article

If you are a developerWorks subscriber, you have a single user license to use WebSphere Application Server, and other DB2®, Lotus®, Rational®, Tivoli®, and WebSphere products -- including the Eclipse-based WebSphere Studio IDE -- to develop, test, evaluate, and demonstrate your applications. If you are not a subscriber, you can subscribe today.

Introduction

A Java™2 Enterprise Edition(J2EE) application server has a highly multi-threaded execution profile that allows multiple transactions to be active simultaneously. The persistent application data associated with these transactions is held in a relational database management system (RDBMS). The application data held in the database is loaded into container managed Enterprise JavaBeans™ (EJBs) when needed by the application within the scope of a transaction. It is important that this data is correctly protected from the competing requirements of those transactions that require read access, and those that require update access. The EJB container, persistence manager and the relational resource adapter and database work together to control the concurrency. Application data integrity is essential, and is ensured by the application server engine. WebSphere Application Server takes care of these low-level details so the application developers do not need to.

To support different database access methods, WebSphere Application Server defines an extension to the EJB deployment descriptor that enables developers to customize the concurrency control settings specific to their applications' transactional needs. Different policies are implemented as declarative annotations that give WebSphere hints on how to access the data. These policies are referred to as Access Intents. WebSphere enables these to be configured manually and can provide performance benefits. Contention on transactional resources, such as a relational database in this case, can become a bottleneck. Tuning the way the application server accesses the persistent data could be used to improve throughput and response times, as well as lead to lower resource contention.

The access intent policies discussed in this article apply to Container Managed Persistence (CMP) 2.x beans only. We are assume the reader has experience with developing EJB applications using WebSphere Studio Application Developer. General knowledge of the SQL language will also make the content more understandable. The next section describes the different attributes of an access intent policy, followed by descriptions of the policies themselves. In the final part of the article, examples are provided to help you use access intents with WebSphere Studio Application Developer V5.1.1.


Attributes of an access intent policy

The following sections describe the main components that make up an access intent policy in WebSphere Application Server V5.1. Access intents are a combination of database-specific isolation levels, locking policies and, in some cases, read-ahead hints.

Each access intent policy defined is an aggregate of a set of properties used to control different aspects of the persistence and concurrency handling involved in dealing with EJB entities. The information described in this article is relevant to WebSphere Application Server V5.1. Although the intention is not to touch upon enterprise specific-concepts, WebSphere Application Server Enterprise Version 5.1 further extends the concepts that are discussed here.

Database isolation level

A transaction processing system must support complete isolation of a transaction from other concurrently running transactions. Complete isolation, however, may have an impact on performance and throughput. If each transaction executes in a serial fashion, our multi-threaded application server would not perform very well. The ANSI SQL-92 standard defines four levels of database isolation that we can use to gain some form of parallelism in our transactions. They are identified with respect to what particular data access characteristics they allow (for example, dirty reads, non-repeatable reads or phantom reads). The isolation level is set on the database connection and, as we will see later, the access intent policy in use will determine how the application server will set this parameter. Different database vendors can use different techniques to ensure that the requirements of isolation level are met.

The four different JDBC™ isolation levels are listed below, with a description of how DB2® handles each one. Other database vendors may implement this differently, but the general idea will be the similar.

  • TRANSACTION_SERIALIZABLE
    This is the strongest isolation level. DB2's internal isolation level for this is referred to as Repeatable Read. All the rows in the database table that are affected by the current transaction will be locked; no other transaction can insert, delete or update a row in the selection set. Locking is also performed so that rows cannot be inserted in a way that would change the selection set used in other transaction. For example, SELECT * FROM orders WHERE Total > 2000 would not only lock the rows that match the predicate condition, but also all rows in the table. This prevents the presence of phantom rows. Uncommitted changes from other transactions cannot be seen.

  • TRANSACTION_REPEATABLE_READ
    Phantom rows can appear with this isolation level. This is because the statement SELECT * FROM orders WHERE Total > 2000 will only lock the rows that meet the condition. If the same statement is reissued within the transaction, the result could be different. It is ensured that the rows updated or read during the transaction cannot be changed by anyone else until the work commits. Repeatable Read maps to DB2's isolation level Read Stability.

  • TRANSACTION_READ_COMMITTED
    DB2 maps this to its Cursor Stability isolation level. If you issue the statement SELECT * FROM orders WHERE Total > 2000 rows will only be locked as the resultset is traversed. Obviously, phantom rows can occur, but more importantly, non-repeatable reads can occur. This happens when a transaction reads the same data twice, while another transaction modifies the data between the two reads, resulting in in a different result for each read.

  • TRANSACTION_READ_UNCOMMITED
    Transactions are not isolated from each other, and can access uncommitted changes from each other. Currently, none of the access intents in WebSphere Application Server will use this isolation level.

Choosing the correct isolation level can be complex. However each access intent policy in WebSphere Application Server will choose an appropriate isolation level for supported databases, relieving the developer from this level of detail. (See Resources.) Knowing what level of isolation WebSphere Application Server puts on its connection to the database can be important if there are other external applications accessing the same database.

Locking strategy

In conjunction with the isolation level, the application server can use two different locking strategies to further control the concurrency of transactions.

  • Pessimistic locking
    A pessimistic locking strategy is one where a lock is obtained early in the transaction and kept until either the transaction is committed or rolled back. Other transactions wanting access to this data wait until the lock is released.
    Figure 1. Illustration of a pessimistic locking scenario.
    Illustration of a pessimistic locking scenario.
    Figure 1 shows the idea behind pessimistic locking. Transaction 1 (Tx1) reads the value 1000 from the database into the balance variable. When Transaction 2 (Tx2) wants access to the row that contains the balance for this account, Tx2 is blocked until Tx1 has updated the balance to 3000 and committed its changes. Tx2 can then proceed with reading the value 3000 and updating it to 4000.
  • Optimistic locking
    The main problem with a pessimistic approach is that transactions have to wait for each other. A way to avoid this is to be more optimistic and believe that it is unlikely that another transaction would want to update the same entity at the same time. With this kind of thinking, locking the data in the beginning of the transaction can be avoided. Instead, it is only locked at the end of the transaction when it is updated. This method requires a way to ensure that the data has not been altered between the time it was read it and when it was updated. This is known as a WriteWriteConflict.
    Figure 2. Illustration of a optimistic locking scenario.
    Illustration of a optimistic locking scenario.
    Figure 2 shows the idea behind optimistic locking. Similar to Figure 1, Transaction 1 (Tx1) reads the balance value as 1000 without locking the row in the database. Transaction 2 (Tx2) is not prevented from doing the same thing, and reads the balance initially as 1000. Before committing the transaction it must check for conflict and finds that the value is now 3000, which is different from the initial value read. It must now abort the transaction and start the transaction again. The task of checking for a conflict can be done in several ways. An extra column can be used in the database to hold a version or a timestamp (see Resources for more information on conflict handling techniques). The update is then made with a conditional expression to only update if this field is the same as when the data was read. One or more fields could be used for the same purpose. It would have to be a field that is updated in each transaction.

The use of optimistic locking offers more concurrent access to the data. The drawback is the need for collision handling which will be very expensive if collision are frequent. For this reason it is only appropriate to apply optimistic locking when collisions are rare. If the application access pattern is predominately update access, then pessimistic approach might be advantageous in that it avoids optimistic concurrency update failures.

Other attributes

An access intent policy in WebSphere Application Server includes a few other properties which are only modifiable in the Enterprise edition, where policies can be customized. One such property is Collection Increment, which allows you to define the size of the collection returned when calling EJB entity multi-finder methods. We can be lazy and set this to a low value, which means that the database must be repeatedly queried to get data as we iterate over the collection. A high value would mean that it is more likely that all data will arrive in one database query, although the cost of maintaining the large collection is higher. To find out more about this and what the default values are for the different Access Intent policies, refer to the WebSphere Application Server Information Center (see Resources), which will also describe the concepts of Collection Scope and Resource Manager Prefetch, all applicable primarily to WebSphere Application Server Enterprise.


Access intent policies

We will now look at the different Access Intents that exist in WebSphere Application Server.

The main identifier for a policy is its locking strategy and type. The type of an access intent can be either read or update. If you assign a read policy to an entity bean, an exception will be thrown if you attempt to update it. That is, you cannot call any setter methods. It is also interesting to consider what isolation level will be used, especially if you have other systems accessing the same database. It is important to realize that different database vendors can have their own meanings of the database isolation level. Most implementations are like that shown in the table below (except for Oracle which is mapped to different isolation levels; see Resources for more information on what isolation level is used with different database implementations). Table 1 shows the seven different policies currently defined in WebSphere Application Server V5.1. This data is based on using DB2 as the RDBMS.

Table 1. Access Intent policies in WebSphere

Policy Type Locking strategy Isolation level
wsPessimisticUpdateUpdatePessimisticRepeatable Read
wsPessimisticUpdateWeakestLockAtLoadUpdatePessimisticRepeatable Read
wsPessimisticUpdateNoCollisionUpdatePessimisticRead Committed
wsPessimisticUpdateExlusiveUpdatePessimisticSerializable
wsPessimisticReadReadPessimisticRepeatable Read
wsOptimisticUpdateUpdateOptimisticRead Committed
wsOptimisticReadReadOptimisticRead Committed

Pessimistic policies

As described previously, the intent of the pessimistic approach is to ensure that the data loaded into the entity bean is locked during the entire duration of a transaction. The normal behaviour of a database access is to get a read lock on the queried data, which gets transformed into an update lock if data is updated. We want to make sure that all the rows are locked when the data is fetched from the database. This can be done by using a specific SQL query referred to as SELECT..FOR UPDATE. The update clause will ensure that an update lock is held on the selected rows. A subsequent transaction issuing the same statement on any of the rows will be blocked until the first transaction commits its changes. There are five different pessimistic policies defined in WebSphere Application Server V5.1. They all have lock hints described by their name, wsPessimistic#hint#, where #hint# further describes our intention with the entity bean.

wsPessimisticUpdate
No specific hint is specified. The isolation level will be set to Repeatable Read and a "SELECT..FOR UPDATE" SQL statement will be used to get an update lock on the row in the database. If you are looking to create a true pessimistic scenario, then this is the policy to use. A drawback is that you cannot have complex queries defined in your finder methods. This is because a SELECT..FOR UPDATE does not support grouping and ordering, so you cannot create a finder that would get a set of rows from the database and order them by a specific column.

wsPessimisticUpdateWeakestLockAtLoad
This is the default policy. If no access intent is specified in the deployment descriptor, WebSphere Application Server will use this hint. Compared to wsPessimisticUpdate, it will not use a SELECT..FOR UPDATE clause to obtain an update lock. The container will load the data with the weakest lock available for the targeted database. This means that the rows will be locked as shared. When an attempt to update is made, the lock will be promoted to an update lock.

wsPessimisticUpdateNoCollision
Uses Read Committed, which is a lower isolation level. It will not use a FOR UPDATE clause when loading the data, so the rows will not be locked. Using this policy, one must be sure that there will be no concurrent update to the same row or range of rows. That is, if concurrent transactions update an entity bean with same primary key, updates could get lost. Avoid using this policy.

wsPessimisticUpdateExclusive
This will ensure that the transaction has exclusive access to the data being updated. Database isolation is set to Serializable and a SELECT..FOR UPDATE statement is used when loading the data. Both readers and writers must wait until the exclusive transaction has committed its changes. This policy should be used with caution since it can create serious bottlenecks in the application. It has the same limitation as wsPessimisticUpdate in that complex queries are not supported.

wsPessimisticRead
If you know that an entity bean will only ever be read and not updated, then this policy will simulate a read-only lock. If an attempt to update the data in the entity bean is made, then an exception will be thrown. Be careful and ensure that no other external applications are accessing the same table(s) with different intentions.

Optimistic policies

By applying an optimistic policy, data will not be locked when the entity bean is loaded. Instead, an overqualified update statement UPDATE .. WHERE will be used when the entity bean is stored back into the database. We will see later how to configure this in WebSphere Studio. Situations where an entity bean is not updated very often will benefit from an optimistic policy. Also if there are a lot more reads than updates on the entity bean, an optimistic locking strategy might improve performance.

wsOptimisticUpdate
This is the only policy we can use if we choose to implement an optimistic locking strategy to update entity beans. It will issue a normal select statement to load the data into the entity bean, perform its updates, and then issue an overqualified update statement when committing the data.

wsOptimisticRead
This only differs from wsPessimisticRead in that the isolation level is set to Read Committed.

Read-ahead hint

An extra feature that can be applied to an access intent policy is a read-ahead hint. This is only applicable when there is a relation defined between entities. The idea is to minimize database calls by caching the related beans. For example, if bean A has a relation to B and C, we specify a read-ahead hint on these relations. Then, when A is loaded, one entity of C is loaded since it is a 1:1 relationship, and a matching number of Bs is loaded since it is a 1-M relationship. Read-ahead hints apply only to the findByPrimaryKey method on CMP 2.x entity beans. The application server will generate a more complex SQL query that will bring in the data from multiple tables. When we later request to access these beans, no database access is necessary.


Figure 3. Entity bean with container-managed relation
Entity bean with container-managed relation.

Read-ahead hints can be defined on more than one level. If D relates to E and E to F, a hint can be created so that when D is loaded the corresponding E and F entities are also loaded. One should not use read-ahead hints unless the corresponding Container Managed Relations (CMR) bean will be touched in the transaction. The hint does imply an extra cost on the database due to the join statement between tables that should be avoided if not needed.


Configuring access intents in WebSphere Studio

The section is a short guide on how to configure access intents in WebSphere Studio Application Developer Version 5.1.1.

A policy can be applied to either an entire bean or on a method in a bean. This article has not discussed access intent policies from a method-level perspective; this can have a complex impact on an application. It is quite easy to cause deadlocks or to prevent connection sharing if different isolation levels are used in the same transaction.

Access intent policy information for entity beans is described in the WebSphere extensions descriptor file, ibm-ejb-jar-ext.xml. Naturally, the intention is that you not have to edit this file, so all this is done for you by WebSphere Studio. To show you how, we will use a simple example of an application that accesses product catalogue data.

Example 1. wsOptimisticUpdate

Figure 4 shows a class diagram of the scenario in which we will use our access intent.


Figure 4. Classdiagram for Example 1
Figure 4. Simple classdiagram of sample scenario

The idea is that a stateless session bean, CatalogBrowser, is used to get a collection of products to display to the user. At the same time, a store administrator can update the product catalogue from an administrative interface. This is done through CatalogAdmin, which also is a stateless session bean. We know that product data is rarely updated, perhaps a few times each month, and customers frequently browse the catalogue for products. With this knowledge, we can optimize the locking strategy for obtaining product entities. Due to the low probability of a conflict in the database, we can confidently use an optimistic locking strategy. To configure an access intent on an Entity bean in WebSphere Studio Application Developer:

  1. In the J2EE Hierarchy, right-click on the EJB module that contains the entity to configure, and select Open with => Deployment Descriptor.
  2. In the main window, select the Access tab.
  3. Scroll down to the WebSphere Extensions section (Figure 5), and select the Add button to display the "Add Access Intent" dialog (Figure 6).
    Figure 5. Deployment Descriptor Editor: Access tab - WebSphere Extenstions.
    Figure 5. Deployment Descriptor Editor: Access tab.

    Figure 6. Add Access Intent dialog
    Figure 6. Add Access Intent dialog
  4. Select the Access intent name from the drop-down list. The read-ahead hint is not selectable since the Product bean in the example does not have any relations to other beans.
  5. Finally, we must specify what should be included in our overqualified update statement when modified data is committed. That is, what fields should be included in the WHERE clause in the SQL UPDATE statement. This needs to be one or more fields in the Product entity that would indicate that an update has been made. In our case, it can be assumed that an update could include any field in the product, and so all fields must be included when doing the check. To do this, you should have database maps defined for your application. When this is done, open the Mapping Editor for the application (Figure 7).
    Figure 7. Mapping editor for product entity bean.
    Figure 7. Mapping editor for product entity bean.
  6. For each field in the CMP entity bean, we can specify if it should be used as an OptimisticPredicate or not by setting the value to either true or false. Java primitive fields are set to true by default. This will not be sufficient for our needs since name, description, and category may be the only field updated by a competing transaction. If they where not included in the overqualified update statement, we would not be able determine that a conflict has occurred.

Example 2. wsOptimisticRead with Read-ahead hint

Now, we will make a small modification to the class diagram from Example 1 that will change the access pattern for our entity bean. Figure 8 shows that we no longer have the CatalogAdmin stateless session bean used to update product data. It is assumed that product data is just read from the database and never updated. We have also introduced a new entity, called component. A product is made up of one or more components, which is realized with a one-to-many relationship between them.


Figure 8. Classdiagram for Example 2.
Figure 8. Simple classdiagram of sample scenario

Since the product and component entity is not updated, a read access type is used. Instead, we can use wsOptimisticRead (Figure 8). When a product entity is loaded, it would be beneficial if the corresponding components could be fetched as well. Follow the steps from Example 1 to set up the access intent; there is no need to define any OptimisticPredicates since we will not update any fields. The read-ahead hint is enabled by checking the corresponding box when creating an access intent. In doing so, we must also specify a preload path to use. This will be the component role in our relationship (Figure 9).


Figure 9. Specify preload path dialog
Figure 9. Specify preload path dialog

Conclusion

This article described the ideas behind optimistic and pessimistic locking strategies in EJB entities, including the different terminology that relates to WebSphere Application Server access intents, database isolation level, read-ahead hints and locking strategy. There are seven different access intent policies defined in WebSphere Application Server that can be applied to CMP 2.x entity beans on either a bean or a method level. The examples in this article demonstrated only bean-level access intent. Assigning access intents at a method-level should be avoided unless you have a really good understanding of what the effects will be.

Using access intents can be important when tuning the performance of an EJB application, especially if it is database intensive. Do not over-tune an application; errors can be introduced if a policy is applied incorrectly. For this reason, the general thinking is that if the performance of an application is already acceptable, there is no need to tune entity bean access. Introducing access intents may make the application design less easy to understand. For example, putting a read type hint on a bean prevents it from being updated. In a multi-user development project, one must now ensure that no one will try to update this bean. However, if performance problems are experienced and database resource contention is high, then tuning the access intents could be useful.


Acknowledgments

I would like to thank John J Stecher and Graham Rawson for their contribution as reviewers.


Resources

About the author

Mattias Persson

Mattias Persson works in the Java Technology Centre, Hursley Park IBM in the UK. He is a member of Java Performance Team and has a personal focus on the measurement and optimization of application server environments. He is a Certified Enterprise Architect for J2EE and received an MSc in Computer Science from Vaxjo University, Sweden, in 2002. He then joined IBM as a graduate.

Comments (Undergoing maintenance)



Trademarks  |  My developerWorks terms and conditions

Help: Update or add to My dW interests

What's this?

This little timesaver lets you update your My developerWorks profile with just one click! The general subject of this content (AIX and UNIX, Information Management, Lotus, Rational, Tivoli, WebSphere, Java, Linux, Open source, SOA and Web services, Web development, or XML) will be added to the interests section of your profile, if it's not there already. You only need to be logged in to My developerWorks.

And what's the point of adding your interests to your profile? That's how you find other users with the same interests as yours, and see what they're reading and contributing to the community. Your interests also help us recommend relevant developerWorks content to you.

View your My developerWorks profile

Return from help

Help: Remove from My dW interests

What's this?

Removing this interest does not alter your profile, but rather removes this piece of content from a list of all content for which you've indicated interest. In a future enhancement to My developerWorks, you'll be able to see a record of that content.

View your My developerWorks profile

Return from help

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=WebSphere
ArticleID=13676
ArticleTitle=IBM WebSphere Developer Technical Journal: Understanding WebSphere Application Server EJB access intents
publish-date=06172004
author1-email=mpersson@uk.ibm.com
author1-email-cc=

My developerWorks community

Tags

Help
Use the search field to find all types of content in My developerWorks with that tag.

Use the slider bar to see more or fewer tags.

Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere).

My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Use the search field to find all types of content in My developerWorks with that tag. Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere). My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Rate a product. Write a review.

Special offers