When using the PessimisticLockManager we are getting deadlock between
different thread processing commands. The system current process
commands that come in via a JMS queue and we have Saga runnning that
also use the command bus to dispatch commands. The system freezes and
the the deadlock is detected in JConsole.
I think the problem is in the inner DisposableLock class. When a
UnitOfWork is cleaning up the acquired DisposableLock instances the
DisposableLock.unlock() is called and the ReentrantLock is unlocked.
Then disposeIfUnused() is called but cannot execute because another
thread is in the DisposableLock.lock() method which is synchronised.
What I dont understand is why the ReentrantLock.unlock() call is not
scheduling the other thread so that is releases its lock on the
DisposableLock instance. Perhaps there is a timing issue.
Here are the thread dumps:
Name: taskExecutor-19
State: WAITING on java.util.concurrent.locks.ReentrantLock
$NonfairSync@154fe2f7 owned by:
org.springframework.jms.listener.DefaultMessageListenerContainer#0-1
Total blocked: 4 Total waited: 71
Stack trace:
sun.misc.Unsafe.park(Native Method)
java.util.concurrent.locks.LockSupport.park(LockSupport.java:158)
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)
java.util.concurrent.locks.ReentrantLock
$NonfairSync.lock(ReentrantLock.java:186)
java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:262)
org.axonframework.repository.PessimisticLockManager
$DisposableLock.lock(PessimisticLockManager.java:118)
- locked org.axonframework.repository.PessimisticLockManager
$DisposableLock@3f46b2b0
org.axonframework.repository.PessimisticLockManager
$DisposableLock.access$100(PessimisticLockManager.java:95)
org.axonframework.repository.PessimisticLockManager.obtainLock(PessimisticLockManager.java:
60)
org.axonframework.repository.LockingRepository.load(LockingRepository.java:
117)
com.maptek.minesuite.pluto.domain.planning.PlannedActivityGraphCommandHandler.handle(PlannedActivityGraphCommandHandler.java:
153)
sun.reflect.GeneratedMethodAccessor330.invoke(Unknown Source)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:
25)
java.lang.reflect.Method.invoke(Method.java:597)
org.axonframework.util.Handler.invoke(Handler.java:110)
org.axonframework.util.AbstractHandlerInvoker.invokeHandlerMethod(AbstractHandlerInvoker.java:
77)
org.axonframework.commandhandling.annotation.AnnotationCommandHandlerAdapter.handle(AnnotationCommandHandlerAdapter.java:
76)
org.axonframework.commandhandling.DefaultInterceptorChain.proceed(DefaultInterceptorChain.java:
62)
org.axonframework.commandhandling.DefaultInterceptorChain.proceed(DefaultInterceptorChain.java:
68)
org.axonframework.commandhandling.interceptors.TransactionInterceptor.handle(TransactionInterceptor.java:
42)
org.axonframework.commandhandling.DefaultInterceptorChain.proceed(DefaultInterceptorChain.java:
60)