-
1. Re: EntityBean Pessimistic Locking an AS7.1
sfcoy Jun 4, 2012 11:50 PM (in response to k_benary)You should get pessimistic locking by default for CMP entity beans (it's one of the reasons that their performance used to suck, but it was spec mandated).
Are you saying that this is not happening?
-
2. Re: EntityBean Pessimistic Locking an AS7.1
k_benary Jun 5, 2012 7:38 AM (in response to sfcoy)No, pessimistic locking works to some extent - I overlooked a detail in the descriptor. However, there are some important questions remaining:
In earlier JBoss versions we used to define container configurations and assigned them to EntityBeans in the jboss.xml. In these configurations we could specify pooling, commit option, interceptors and others. However, this file is ignored in AS7.
In AS7 it seems that we can use the <optimistic-locking> entry in the jbosscmp-jdbc.xml to decide whether or not optimistic locking is to be used. (Right?)
An EntityBean where we add
<optimistic-locking>
<version-column/>
<column-name>ocColumn</column-name>
<jdbc-type>BIGINT</jdbc-type>
<sql-type>NUMERIC (38)</sql-type>
</optimistic-locking>
is controlled optimistically using the version column 'ocColumn'. From the outcomes of our test suites we assume, that the behavior is equivalent to the "Instance Per Transaction CMP 2.x EntityBean" from earlier versions, which means:
- commit option C
- use of a per-transaction instance cache
- sync-on-commit-only = false (include updates in non-PK finders)
When we ommit the <optimistic-locking> entry, we actually see pessimistic locking. But we have no clue about the inner behavior. Think of the following scenario using entity A and B (both pessimistic):
- Process 1: read A, wait 5 seconds, then read B
- Process 2: wait 1 second, read B, wait 2 seconds, then read A
With pessimistic locking this is a textbook application deadlock. In earlier versions this deadlock was detected by JBoss and a org.jboss.util.deadlock.ApplicationDeadlockException was thrown. In AS7 both threads are stuck in:
java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:811)
java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:842)
java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1178)
org.jboss.as.ejb3.tx.OwnableReentrantLock.lock(OwnableReentrantLock.java:86)
org.jboss.as.ejb3.component.entity.interceptors.EntityBeanSynchronizationInterceptor.processInvocation(EntityBeanSynchronizationInterceptor.java:80)
After exactly one hour we see a
javax.ejb.TransactionRolledbackLocalException: No transaction is running
at org.jboss.as.ejb3.component.interceptors.EjbExceptionTransformingInterceptorFactories$2.processInvocation(EjbExceptionTransformingInterceptorFactories.java:93)
- Does JBoss 7.1 not detect application deadlocks anymore?
- Where is this timeout defined?
Another important question is this: In earlier JBoss versions we used the <row-locking> element in the jbosscmp-jdbc.xml for pessimistic entities where we did not want to wait until an existing lock is gone.
- Is there a way to achieve this behavior on JBoss7 too?
Thanks, Klaus
-
3. Re: EntityBean Pessimistic Locking an AS7.1
k_benary Jun 11, 2012 11:09 AM (in response to sfcoy)I went on investigating the pessimistic concurrency for EJB 2.1 EntityBeans and found two more issues - one of them reather serious:
1. Reuse of a PK in the same TA
If I delete an EntityBean with a primary key X and then create it anew in the same TA with the same PK X the following Error log appears:
16:41:42,980 ERROR [org.jboss.as.ejb3] (EJB default - 10) JBAS014138: Exception releasing entity: java.lang.IllegalStateException:
JBAS014172: Instance [org.jboss.as.cmp.component.CmpEntityBeanComponentInstance@70dcfe0a] not found in cache
at org.jboss.as.ejb3.component.entity.entitycache.ReferenceCountingEntityCache.release(ReferenceCountingEntityCache.java:85)
However this does not affect the result of the operation. The creation is successful.
2. Transaction isolation
- Transaction1 reads an EntityBean with PK X and sets the value of the field f1 to "Value1".
- Transaction1 waits for 5 seconds
- Transaction2 tries to read EntityBean with PK X while Transaction1 is still waiting (holding the lock).
- Transaction1 - after 5 seconds - throws a RuntimeException which should rollback the transaction.
- Transaction2 now gets hold of the EntityBean with PK X - and finds "Value1" in f1 !
This means, TA2 cann see the result of TA1 which was rolled back!
I made a reproducer for both issues. I can post it wherever you like. (Should I file a Jira issue?)
We use pessimistic locking for the creation of gapless number ranges. This issue is a blocker for us.
Klaus
-
4. Re: EntityBean Pessimistic Locking an AS7.1
jaikiran Jun 11, 2012 11:20 AM (in response to k_benary)Please do file a JIRA along with the details and the applications. I still have to look at one other entity bean issue that you reported. I'll come to these some time soon.
-
5. Re: EntityBean Pessimistic Locking an AS7.1
welle Jul 3, 2012 5:57 AM (in response to jaikiran)From what I can see the Jira created (AS7-4976) only covers issue #2 above. What about #1?
Perhaps the following code in ReferenceCountingEntityCache.java (Method release):
if (cacheEntry == null) {
throw new IllegalArgumentException("Instance [" + instance + "] not found in cache");
}
should be changed to
if (cacheEntry == null) {
// TODO: Perhaps log "Instance [" + instance + "] not found in cache" at debug level
return;
}
-
6. Re: EntityBean Pessimistic Locking an AS7.1
ion_mayank Sep 17, 2012 2:38 AM (in response to k_benary)Hi Klaus,
I am also facing the same issue with Pessimistic locking in JBOSS7 when my code starts a New Transaction from a existing transaction and both using the same Entity Bean.
My server hangs up completely in acquiring a lock and transaction rollback exception is thrown.
I have also filed the JIRA - https://issues.jboss.org/browse/AS7-5539. Please have a look.
Thanks,
Mayank
-
7. Re: EntityBean Pessimistic Locking an AS7.1
cinzko Sep 19, 2012 5:45 AM (in response to k_benary)Hi,
i could also easily reproduce such a deadlock which is not detected by the jboss 7. I have an EJB 2.1 entity bean (SystemProperty with 2 attributes "key" and "value") which is using the default pessimistic locking handling and a stateless sessionbean with read and write methods for the entitybean (getSystemProperty/setSystemProperty).
Thread 1 and Thread2 each call a stateless sessionbean-method (transaction-attribute=REQUIRED) which perform the actions listed below.
Thread1: Thread2
set key1=value1 set key2=value2
sleep 1 second sleep 1 second
get key2 get key1 <- "deadlock" (not detected)
JBoss 7.1 is not able to detect this classical deadlock situation and "hangs" until the transaction timeout is reached.
Is this a known defect or is there a possibility to change some configuration to enable the deadlock-detection (its not possible to switch to optimistic locking, because we need pessimistic locking in some cases).
Thanks,
Christian