We're getting deadlocks in QueuedPessimisticEJBLock.waitForTx() under JBoss 3.0.2, and I'd really appreciate any pointers anyone could give.
We have 2 related (CMR) entity beans, Verification and Merchant, with the Merchant having many Verifications. We pass the Merchant primary key in the create() method for the Verification, and in its ejbPostCreate() we load the Merchant and set it in the CMR field.
We can get this to work using commit option 'A'. However, when we use commit option 'B', concurrent requests creating Verifications for the same Merchant deadlock in QueuedPessimisticEJBLock.waitForTx(), via JDBCCMRFieldBridge.invokeAddRelation(). After 5 seconds, the lock waits time out and the transactions are rolled back.
From the SQL being generated, it appears that the deadlock sequence is something like this:
1 A ejbCreate() inserts into the Verification table
2 B ejbCreate() inserts into the Verification table
3 A ejbPostCreate() selects merchant PK
4 A ejbPostCreate() selects merchant data
5 A ejbPostCreate() selects all Verifications for merchant
6 B ejbPostCreate() selects merchant PK
From what I can see, the problem is in the lock ordering - each thread is accessing Verification, then Merchant, then Verification again.
My questions are:
- Is there some way we can configure the system to avoid the deadlock (other than using commit option A)?
- Are read-mostly caches available? If so, would loading the merchant from read-only avoid the locking issue?
- Would we be better to pass the MerchantLocal in to the Verification.create()? [We passed in the primary key so that we could run remote JUnit tests against entity beans without having to use Cactus].
Thanks in advance.
Cheers ............... JD
3.0.2 and earlier have a race condition bug that can cause this behaviour, even when using Commit Option A.