|[eclipselink-dev] Fix Review for bug# 259993 - [branch trunk] - WebSphere 7.0 em.clear() callback within commit causes a subsequent em.find() to hang|
Developers,The following fix is ready for general review and will be checked into the EclipseLink trunk branch tonight.
http://bugs.eclipse.org/259993 Full Core/JPA/testing patch https://bugs.eclipse.org/bugs/attachment.cgi?id=125911&action=diff Checked into the 1.1 branch under http://fisheye2.atlassian.com/changelog/eclipselink/?cs=3447 Code Reviewed: Thank you Gordon Yorke, Andrei Ilitchev, James Sutherland Cause: On WebSphere 7 we hang on a find() after a commit().A WebSphere 7.0 (6.1 is ok) em.close() callback in the middle of a commit() is causing the entityManager state to be reset before the transaction completes. The result of this is that we end up having pending changes that should have been commited but when committed during ReadObjectQuery on a em.find() for example - when we attempt to get a lock - we are blocked by the previous acquire() that did not release() because of the WAS em.close() that reset our UnitOfWork state - mid transaction. RepeatableWriteUnitOfWork.clearForClose(boolean) line:126 EntityManagerImpl.clear() line: 220 JPAEMPool.putEntityManager(EntityManager) line: 147 JPATxEntityManager.closeTxEntityManager(EntityManager,boolean) line: 299
Fix:Fully clear the entityManager "only" when we are in a non *Pending state/lifecycle - in which case we only clear the cache - not the em state. We allow WebSphere 7.0 to do a partial cache em.clear() during a commit() without resetting the entityManager state/lifecycle flag
Reproduction: 1 - container manged stateless session bean running on WebSphere 7.0 2 - persist() and commit() a single entity 2a - we acquire locks in beforeCompletion()2b - during the commit() but before afterCompletion() - WebSphere calls em.close() which calls uow.clearForClose() - it is here that we clear the em and set the state/lifecycle back to 0 (Birth) from 4 (*Pending)
Details of the fix: EclipseLink on WebSphere 7.0 is supported. Part 1) uow.clearForClose()- we do not fully clear the em on a clear() call unless the state/lifecycle of the entityManager is 0,3,5 or 6, if the state/lifecycle is 1,2 or 4 (*Pending) we only clear the cache. - the em state remains uncleared, the afterCompletion code in the transaction commits normally.
Part 2) uow.mergeClonesAfterCompletion() - added code to save the current thread on acquire- on a merge we check that the current thread and the current thread on the previous acquire are equal - if they are not then we overwrite the active thread on the mutex on all acquired locks in the mergeManager
Test Results: See comments 28-30+ in the bug thank you /michael
Back to the top