I have a client that gets a reference to an entity bean A. Say it calls enityA.getCity(). Now if another client calls entityA.getState(), will this have to wait untill the first caller is done with the transaction(it entered into when it called getCity())?
It depends on the locking mechanism employed by the server, JBoss by default (I think) puts a read lock on the entity (the constraint you described), but others may only put a write lock (there are several different types of read and write locks) - either way its usually configurable
That depends on the record being processed. Lets say a client calls getCity() for a particular record (after doing a findByPrimaryKey). This will pull out an entity bean from the pool, that bean will get loaded with the data from the database for that record. Before loading, the record will be locked for the transaction.
Meanwhile if another client comes along and calls getState() for a different record in the same table (after doing findByPrimaryKey to get the component interface reference for that entity), another instance of the same entity bean will be activated and loaded with that entity's data. Because this is a different record, it is in no way related to the previous record. Now this record will be locked for the current transaction and if the application is multithreaded (which it will be 99%), this transaction can proceed concurrently with the previous one.
Now, if another client request comes for one of these 2 records already participating in the transaction, then there is no option but to wait for the transaction to complete. For the new entity bean instance to be loaded with the entity's data, the lock on that entity needs to be released which means the current transaction has to end
The lock is at the record level (entity level) and not at the table level (entity type)
posted 14 years ago
Thankyou for your responses. It makes things clear for me now.
posted 14 years ago
A followup question: say clientA loads entityA and invokes the setState() and goes on to do something else without finishing the transaction. Then, clientB executes a finder method to find all entities with a particular state, since the record loaded by client A is locked, will the find method wait till clientA releases the record?
posted 14 years ago
I am not 100 % sure about this. I think the finder call from the second client will have to wait, because if that proceeds and the second client gets a component interface reference to that locked entity, what would happen if client A proceeds to delete that entity. Then, when client B which would have got a reference to the deleted entity will try to make a business method call on it and the container would try to load a bean instance with the entity details and it won't find that entity at all. Not sure what would happen then. So I think the lock needs to be released before the finder call can proceed. But then it would also depend on the type of lock used by the database, if its a write lock alone, then the finder call need not wait.
Someone else can throw some light on this.
That said, one of the advantages of using entity beans is that these kind of concurrency problems are handled internally by the container. Hence you don't have to worry about these kinds of problems. Thats one good thing about entity beans. The container and the database will work together to handle concurrency and the way it handles may be container dependent
The answer is not easy; fortunately, it is vendor-dependent and not in the exam. For those who are interested, read on.
The question that needs to be answered is what is the entity bean's concurrency strategy, meaning how the EJB container should manage concurrent access to the bean. It determines how and when the container synchronizes its cached copy of the entity with the database. For a server such as WebLogic Server, there are three strategies.
Exclusive Concurrency With exclusive concurrency, the container places an exclusive lock on cached EJB instances when the bean is associated with a transaction. Other requests for the EJB instance are blocked until the transaction completes. Exclusive locks are local to the server instance, so this strategy is most appropriate for a single server architecture. When used in a cluster, exclusive concurrency serializes all requests to a bean instance within a server instance, but concurrency between servers in the cluster that access the same bean concurrently is governed by the database.
Multiple clients can use the exclusive concurrency option to access entity EJBs in a serial fashion. Using this exclusive option means that if two clients simultaneously attempt to access the same entity EJB instance (an instance having the same primary key), the second client is blocked until the EJB is available.
Database Concurrency With database concurrency, concurrency control for an EJB for each transaction is deferred to the underlying datastore. WebLogic Server allocates a separate entity bean instance to each transaction and allows concurrency control to be handled by the database. This is the default option.
With the Database mechanism, the EJB container continues to cache instances of entity bean instances. However, the container does not cache the intermediate state of a bean instance between transactions. Instead, WebLogic Server issues a SQL SELECT for each instance at the beginning of a transaction to obtain the latest EJB data. A SQL UPDATE is issued if there are changes.
The request to commit data is subsequently passed along to the database. The database, therefore, handles all concurrency control and deadlock detection for the EJB's data.
Optimistic Concurrency As with the Database concurrency strategy, Optimistic concurrency gives each transaction its own bean instance. The Optimistic concurrency strategy does not hold any locks in the EJB container or the database while the transaction is in process.
Concurrency strategies present a trade-off between performance and freshness of data. For instance, the Database concurrency strategy carries a risk of deadlock, as each transaction must obtain an update lock from the database. However, you can configure the server to get the database to take out an exclusive lock when the read is done, avoiding the deadlock that can occur when a read lock is upgraded to an exclusive lock. The transaction isolation level can be used in combination with Database concurrency to achieve the desired concurrency behaviour.
And what is the isolation level? A transaction's isolation level is the degree to which it exposes updated but uncommitted data to other transactions. Allowing access to uncommitted data can improve performance, but increases the risk of incorrect data being supplied to other transactions.
Let's look at the definition of the method-level isolation settings for an EJB. If client B's transaction isolation setting is TRANSACTION_READ_COMMITTED, which is supported by just about every JDBC driver, then it will only be able to view committed reads.
Some drivers support TRANSACTION_READ_UNCOMMITTED. This allows, amongst other things, dirty reads. So, B's transaction would read data which A's transaction had updated but not committed.