cuncurrency problem in CMP
mostofizadeh Jun 28, 2002 4:28 PMmostofizadeh:
I run the same scenario under weblogic 7.0 and did not get the exception.
mostofizadeh:
I verified that Progress does support TRANSACTION_SERIALIZABLE. I also run some more tests on Progress to verify the behavior of the levels. I also run the same test scenarios against Oracle 8 and still got the same exception.
Here are some thoughts;
I am calling the CMP findAll (which I have declared this eql for in the descriptor, SELECT OBJECT(o) FROM Organization o), and iterating through the CMP local references and calling the getter methods in a method of the session facade. Both the session facade and CMP beans have transaction demarcation 'Required' on all of their methods. My question is, does the container execute the findAll method inside the transaction, which would make me believe that in a Serializable transaction, the remove call in thread-1 must fail since findAll is already has the lock.
davidjencks:
Are you sure Progress actually supports transaction isolation? For
instance, Hypersonic does not object if you call setTxIsolation(any legal
value) but the only isolation level supported is ReadUncommitted. I can't
see how this is could be a problem with JBoss, but I could be missing a
lot. If your db actually does support tx isolation levels please post this
on the User mailing list or Database forum.
mostofizadeh:
I have come across an issue with jboss (the GA version) running a concurrency test. The problem is rather easy to explain.
The test scenario is performed as a JUnit test case. I use JUnitPP to run
the JUnit test case in iterations and concurrent threads.
Note: I am not sure if this matters, the entity below (organization) is in a 1:m CMR. 1(organization):m(users)
thread-1
-----------
method1-create organization A
method2-read organization A
method3-readAll (SELECT OBJECT(o) FROM Organization o), look for
organization A in the collection and call a getter method on the reference( getId() )
method4-find organization A
method5-remove organization A
thread-2
-----------
method1-create organization A
method2-read organization A
method3-readAll (SELECT OBJECT(o) FROM Organization o), look for organization A in the collection.
note: Before calling the getter method on the reference, thread-1 calls remove (added timestamps and noticed the race condition),
once call the getter is called the container throws:
javax.ejb.NoSuchEntityException: Entity not found: primaryKey=A
method4-find organization A
method5-remove organization A
A few notes about the transaction demarcation and isolation levels. I am
using Progress 1.9.d database and its JDBC drivers.
-All these method calls are made from a JNDI client to a stateless
session
bean (session facade)
-The session methods all have <trans-attribute>Required</trans-attribute>
-The session methods intern call the CMP entity methods which also have
<trans-attribute>Required</trans-attribute>
so the transaction starts when calling the session method.
-At first I was not setting the transaction isolation level (what is the
default isolation level?) Later I set it to TRANSACTION_SERIALIZABLE and still got the same
exception. My understanding was if the findAll method and the getter methods on the references in the collection
were called in the same transaction (with a higher isolation level), there should be not a race condition.