Concurrency Control

Enterprise applications often try to balance the application scalability with concurrency issues. To improve the concurrent access for entity beans, server enables to defer locking services to the corresponding database. This strategy specifies how the EJB container should manage concurrent access to an entity bean.

This chapter discusses the concurrency control for entity beans.

Locking types

Locking is used to ensure transactional and database integrity. Locking prevents the data being changed by two or more users at the same time. If locking is not used, the data in the database may turn logically incorrect thus producing unexpected results to queries.

Lock Manager Pramati has an elaborate lock manager framework that manages the locks obtained by the container on various entities. Lock manager framework is used to determine which lock mechanism is used. This is the pessimistic concurrency control behavior of the Pramati Server. This option is for BMP1.1 and 2.0 and CMP2.0 beans.

Local Lock Server (LLS) This is a lock server running within a standalone Pramati server (or in each node of a cluster). The lock-server is used to lock resources within the single server/node. The local lock server is used to lock Entity Beans in standalone servers.

Super-Lock-Server (SLS) Super-lock-servers are used in the Pramati cluster. The super-lock servers work with the local lock servers. The lock manager manages the access and the cluster semantics.

In case of Clusters, whenever a client requests access to a particular object in a specified node, the Lock manager checks for the compatibility with the existing locks.

A lock on a resource is acquired from the SLS to the LLS.

Once acquired, all further lock accesses to that resource is managed from within the LLS. Until one of the other nodes (for example: node 1 in the cluster needs the same resource.) This node then requests the SLS for the lock, and the SLS will request the node1-LLS to release the lock and then SLS passes the lock to the node-2.

DB Lock Module- Locking using Select-for-update The DB lock module is used to enable locking via placing UPDATE locks in the database. Whenever a CMP bean is to be locked, it is loaded using SELECT.FOR UPDATE sql. The lock is acquired in the database and will get released only at the end of the transaction. This is typically followed in environments where multiple sources may update the data store.

Tuning OR-MAP parameters

This xml contains OR-Map related information and flags for setting concurrency and exclusion type.

These parameters are specific to CMP beans.

Exclusion type

The J2EE specification does not require the application to necessarily have exclusive database access, but it provides various Commit Options (A,B,C) as in 9.1.10 in EJB 1.1 specification and 10.5.9 of EJB 2.0 specification.

Commit Options:

Exclusive

Implies that the database is accessed in exclusive mode. No external entity/application will access/modify the database.

Performance advantage ejbLoad() callback avoided at the beginning of the transaction; bean state need not be synched with the DB.

The default option is Non-Exclusive, but can optionally be set to Exclusive, if the container has exclusive access to DB.

When set to Exclusive, do the following to get the optimal performance:

The Bean pool size is a measure of concurrency and not the database size and since bean activation/passivation are not expensive operations when commit, option is set to Non-Exclusive. The bean gets freshly loaded every time in the beginning of transaction even if it was in Ready State.

If the commit option is set to Exclusive, the expensive EJB Loads can be avoided if the bean is in Ready State. Hence, for higher performance, the bean pool size for a particular bean should be set equal to the DB size if the DB is of reasonable size like <5000, even if the concurrency is not so high on such beans to justify a pool size so high.

If the DB is large for the given bean and the access pattern is quite random, then a higher pool size with exclusive DB access will not greatly enhance the performance. A pool size as high as the database size for such big data is not advisable, since exceptionally higher pool size for a bean implies larger size data structures maintained by the container.

This would imply higher search times and higher consumption of memory too. Hence, it would be wiser to load when the bean is not found in the ready state.

With Pramati server you can choose between Commit Option A and B.

Non-Exclusive

This is applicable for both Stand Alone and clustered environments. Application does not have exclusive access to DB. A bean is always loaded fresh from DB before the beginning of a transaction.

Clustered deployment always works in non-exclusive mode.

Concurrency type

Enterprise applications often try to balance the application scalability with concurrency issues. To improve the concurrent access for Entity Enterprise beans, the Pramati Server allows different concurrency modes. It enables pessimistic concurrency at the application server level or defers locking services to the corresponding database. However, optimistic concurrency is enabled using verified updates.

When writing the entity bean business methods, the Bean Provider does not have to worry about concurrent access from multiple transactions. The Bean Provider may assume that the container will ensure appropriate synchronization for entity objects, using isolation level set by user, that are accessed concurrently from multiple transactions.

In pessimistic approach, concurrent transactions are synchronized by using locks. These locks are maintained by the application server or pushed to the underlying persistent store. This mechanism is useful when there are relatively more concurrent transactions on the same entity identity.

Isolation

Repeatable Read

This is the default setting for entity beans deployed in Pramati Container. This is a pessimistic behavior.

A single bean instance is created irrespective of number of concurrent requests; the app-server takes care of serializing requests to this particular instance. A load happens before the beginning of a transaction, if the application doesn't have exclusive access to db in Standalone. The state of the bean is always updated based on the outcome of the dirty check (store if dirty)

Case1: Exclusive DB

Performance advantage An exclusive lock on the instance's state in the DB is postponed till a ejbStore() callback happens as part of commit on a transaction. A delayed lock implies connections are locked for limited time. Since it is a limited resource usage, it results in higher performance.

Case2: Non-Exclusive DB

At the beginning of a transaction, a bean is loaded fresh and an exclusive lock is acquired on the particular row in db (SELECT FOR UPDATE). Connections are locked up for the complete transaction starting from beginning to end. If database locks are not supported, app server locking is enabled using lock server.

Optimistic Repeatable Read

For multiple instances of beans created, one per each concurrent transaction, the methods in the beans execute concurrently.

Bean's state may get loaded fresh from DB depending on if the bean has exclusive access to DB. But on committing a transaction, a verified update is done always irrespective of if the bean state got modified as part of the transaction. The container validates the state of the cache against the database

Use Case Scenario If the bean is highly concurrent in its usage, the container managed fields rarely get modified as part of transaction, and the modified bean state is dependent on the initial state of the bean at the beginning of transaction.

Example

A highly concurrent ItemBean whose price gets occasionally modified, dependent of the previous price is likely to be increased by 10%.

Performance advantage For a Standalone deployment with exclusive DB access, a load from DB is avoided and concurrent transactions that require shared lock for get accessor methods can go ahead and access the bean.

Read Committed

For multiple instances of bean created one per each concurrent transaction, the methods in the beans execute concurrently.

Bean's state always gets loaded fresh from DB in the beginning of transaction. At the time of committing, the transaction the bean's CMF are compared and a blind update is done only if the state is dirty. If not used properly, this option can lead to lost-updates.

Use case Scenario If the concurrency is high on the bean and the modification of bean's CMF is not dependent on the previous state of the bean, isolation could potentially overwrite changes from multiple concurrent transactions.

Example

A highly concurrent ItemBean whose price gets modified, absolutely independent of the previous price.

Performance advantage Concurrent transactions that require shared lock for get accessor methods can go ahead and access the bean, an update call is avoided if the bean state was not modified as part of the transaction.

Note: This parameter can be manually modified.

Concurrency Control Strategies

Concurrency Control Read Committed Repeatable Read Optimistic Repeatable Read Read Only Remarks
Exclv Non-exclv Exclv Non-exclv Exclv Non-exclv
Load No Yes No Yes No During store No Load means database fetch to synchronize bean from Ready Pool
Store Yes Yes Yes Yes Yes Yes No Actual store only when any state is changed
App server locks No No Yes Yes (if DB locks not supported) No No No App server locking uses locks and Super Lock Server
DB locks No No No Yes (if DB locks supported) No No No DB locks taken using Select For Update
Deadlocks No No Yes Yes No No No When deadlocks, use RC/ORR
Tx rollbacks No No No Yes (if DB locks timeout) Yes Yes No DBlocks can timeout using wait/nowait
Multiple bean access Yes Yes No No Yes Yes Yes Multiple beans for same identity to different Tx
Multiple threads wait No No Yes Yes No No No Indicate if threads have to wait on same identity
Range of concurrent Tx Medium Medium High High Medium Medium Any  
Nature of concurrent Tx High reads, low updates High reads, low updates Any reads, high updates Any reads, high updates Any (preferably high reads, low updates) Any (preferably high reads, low updates) Only reads   

Terms used in the table:
Tx transaction
Exclv Exclusive
Non-exclv Non-exclusive
DB Database
App Application
RC Read Committed
ORR Optimistic Repeatable Read

Setting the Optimistic Concurrency Control(OCC) for BMPs

The serialization of transaction severely limits the scalability of application. When number of concurrent users increases, the number of parallel transactions also increases. But serialization of transaction will make other transactions wait for the currently executing transaction to complete. Therefore to achieve high scalability there should be a way to execute these transactions concurrently without compromising on the ACID1 property of the transaction. When transactions are executed in parallel, they are called concurrent transactions. This mechanism of execution is known as optimistic concurrency control.

The main advantage of OCC method is immediate response times, but on the downside you cannot be sure that the action will be performed until the lock has been accepted or rejected. This depends on the probability of concurrent access. For example, if there are many users the probability of concurrent access is greater and so pessimistic concurrency control might be used, whereas if not many users exist, concurrent access will be rarer so OCC might be better used. By default the pessimistic mode is selected.

To set the OCC for BMPs, you have to start the server with the following option:
-Dcom.pramati.ejb.nolockbmp=true

Selecting the Concurrency Type for CMPs in Deploy Tool

Click on the Concurrency tab to edit the concurrency properties for entity beans. The concurrency modes supported in Server are:

The optimizations can be performed using either of the two locking methods

In case of EJB 2.0 applications, the Optimistic Repeatable Read provides the following options: