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 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.
This xml contains OR-Map related information and flags for setting concurrency and exclusion type.
These parameters are specific to CMP beans.
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.
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.
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.
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)
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.
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.
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.
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.
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.
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.
| 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 |
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
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:
After the verification the update options are: