In the JBoss reading that I have done, the JBoss application server uses a transaction lock to ensure that there is only one active instance of a given entity bean (one with a given primary key) in memory at one time. If any method at all is invoked on an entity bean within a transaction, no other transaction can have access to this bean until the holding transaction commits or is rolled back.
In my testing I am not seeing this behavior. The testing results are consistent with no transaction lock ever being placed. I am hoping that someone can suggest why - and how I can get the default behavior.
Summary of environment:
* JBoss 5.1.0.GA server/default + Oracle datasource
* Oracle 10g
* EJB 3 Entity Beans with CMP
The Entity Beans do not use any custom primary key classes. A Java Long is used for all primary keys. No equals or hashCode method overrides exist. standardjboss.xml has not been modified and no custom container-configurations are implemented. There is no explicit mapping of the entity beans to a container configuration -- JBoss default determination of entity bean to container configuration is used. This should be a container with commit option B and QueuedPessimisticEJBLock.
Summary of test:
Command-line client program accesses a stateless session bean remote interface to execute the test method (executeConcurrencyTest) to update an Entity Bean (Person).
* retrieve a Person using EntityManager.find(Person.class, <primary key value>)
* update a field in the record
* (optionally) pause processing for ~1 minute using an ldap retrieval that happens to be very slow
* return from method
Two overlapping test runs, using the same Person primary key, are executed as follows:
* Start Run#1 with the optional pause selected.
* Wait until logging indicates that Run #1 is "pausing".
* Start run#2 without the optional pause.
* Run#2 completes successfully and its update is seen via SQLDeveloper.
* Run#1 completes successfully and its update is seen via SQLDeveloper.
What was expected is that run#2 would block at the EntityManager.find until run#1 transaction completed at the method return, because of a JBoss transaction lock, but this did not happen.
Trace-level logging during test runs does not show any entries for EntityLockInterceptor, which is responsible for scheduling any locks that must be acquired. Of course, this could just mean that no trace-level logging is included in the java code.
EntityLockMonitor service is enabled for jmx-console. Neither listMonitoredBeans nor printLockMonitor show any entries at all during the test runs. AverageContenders, MedianWaitTime, and MaxContenders are always zero.