Module org.eclipse.persistence.core
Class WriteLockManager
java.lang.Object
org.eclipse.persistence.internal.helper.WriteLockManager
INTERNAL:
Purpose: Acquires all required locks for a particular merge process. Implements a deadlock avoidance algorithm to prevent concurrent merge conflicts.
Responsibilities:
- Acquires locks for writing threads.
- Provides deadlock avoidance behavior.
- Releases locks for writing threads.
- Since:
- 10.0.3
-
Field Summary
Modifier and TypeFieldDescriptionstatic final int
static final int
protected ExposedNodeLinkedList
-
Constructor Summary
-
Method Summary
Modifier and TypeMethodDescriptionacquireLockAndRelatedLocks
(Object objectForClone, Map lockedObjects, Map refreshedObjects, CacheKey cacheKey, ClassDescriptor descriptor, AbstractSession cloningSession) INTERNAL: This is a recursive method used to acquire read locks on all objects that will be cloned.acquireLocksForClone
(Object objectForClone, ClassDescriptor descriptor, CacheKey cacheKey, AbstractSession cloningSession) INTERNAL: This method will return once the object is locked and all non-indirect related objects are also locked.void
acquireRequiredLocks
(MergeManager mergeManager, UnitOfWorkChangeSet changeSet) INTERNAL: This method will be the entry point for threads attempting to acquire locks for all objects that have a changeset.static void
addCacheKeyToMapWriteLockManagerToCacheKeysThatCouldNotBeAcquired
(Thread thread, ConcurrencyManager cacheKeyThatCouldNotBeAcquired, long whileStartDate) The thread was doing its while loop to acquire all required locks to proceed with the commmit and it realized there was one cache key it is unable to acquireappendLock
(Object primaryKey, Object objectToLock, ClassDescriptor descriptor, MergeManager mergeManager, AbstractSession session) INTERNAL: This method will be called by a merging thread that is attempting to lock a new object that was not locked previously.protected CacheKey
attemptToAcquireLock
(ClassDescriptor descriptor, Object primaryKey, AbstractSession session) INTERNAL: This method performs the operations of finding the cacheKey and locking it if possible.protected CacheKey
checkAndLockObject
(Object objectToLock, Map lockedObjects, Map refreshedObjects, DatabaseMapping mapping, AbstractSession cloningSession) INTERNAL: Simply check that the object is not already locked then pass it on to the locking methodstatic void
Remove the current thread from the map of object ids with change sets that are about to bec ommitedstatic void
Before the problematic while loop starts we should always clear for this thread the set of cache keys it could not acquire.Getter forMAP_WRITE_LOCK_MANAGER_THREAD_TO_OBJECT_IDS_WITH_CHANGE_SET
static Map
<Thread, Set<ConcurrencyManager>> Getter forTHREAD_TO_FAIL_TO_ACQUIRE_CACHE_KEYS
static void
populateMapThreadToObjectIdsWithChagenSet
(Thread thread, Collection<ObjectChangeSet> objectChangeSets) Before a thread starts long wait loop to acquire write locks during a commit transaction the thread will record in this map the object ids it holds with chance sets.void
releaseAllAcquiredLocks
(MergeManager mergeManager) INTERNAL: This method will release all acquired locksstatic void
removeCacheKeyFromMapWriteLockManagerToCacheKeysThatCouldNotBeAcquired
(Thread thread, ConcurrencyManager cacheKeyThatCouldNotBeAcquired) A cache keys was successfully acquired we want to make sure it is not recorded in the map of cache keys that could not be acquired.void
transitionToDeferredLocks
(MergeManager mergeManager) INTERNAL: This method will transition the previously acquired active locks to deferred locks in the case a readlock could not be acquired for a related object.traverseRelatedLocks
(Object objectForClone, Map lockedObjects, Map refreshedObjects, ClassDescriptor descriptor, AbstractSession cloningSession) INTERNAL: Traverse the object and acquire locks on all related objects.protected CacheKey
waitOnObjectLock
(ClassDescriptor descriptor, Object primaryKey, AbstractSession session, int waitTime) INTERNAL: This method performs the operations of finding the cacheKey and locking it if possible.
-
Field Details
-
MAXTRIES
public static final int MAXTRIES- See Also:
-
MAX_WAIT
public static final int MAX_WAIT- See Also:
-
prevailingQueue
-
-
Constructor Details
-
WriteLockManager
public WriteLockManager()
-
-
Method Details
-
acquireLocksForClone
public Map acquireLocksForClone(Object objectForClone, ClassDescriptor descriptor, CacheKey cacheKey, AbstractSession cloningSession) INTERNAL: This method will return once the object is locked and all non-indirect related objects are also locked. -
acquireLockAndRelatedLocks
public CacheKey acquireLockAndRelatedLocks(Object objectForClone, Map lockedObjects, Map refreshedObjects, CacheKey cacheKey, ClassDescriptor descriptor, AbstractSession cloningSession) INTERNAL: This is a recursive method used to acquire read locks on all objects that will be cloned. These include all related objects for which there is no indirection. The returned object is the first object that the lock could not be acquired for. The caller must try for exceptions and release locked objects in the case of an exception. -
transitionToDeferredLocks
INTERNAL: This method will transition the previously acquired active locks to deferred locks in the case a readlock could not be acquired for a related object. Deferred locks must be employed to prevent deadlock when waiting for the readlock while still protecting readers from incomplete data. -
traverseRelatedLocks
public CacheKey traverseRelatedLocks(Object objectForClone, Map lockedObjects, Map refreshedObjects, ClassDescriptor descriptor, AbstractSession cloningSession) INTERNAL: Traverse the object and acquire locks on all related objects. -
acquireRequiredLocks
INTERNAL: This method will be the entry point for threads attempting to acquire locks for all objects that have a changeset. This method will hand off the processing of the deadlock algorithm to other member methods. The mergeManager must be the active mergemanager for the calling thread. Returns true if all required locks were acquired This is wrapper method with semaphore logic. -
appendLock
public CacheKey appendLock(Object primaryKey, Object objectToLock, ClassDescriptor descriptor, MergeManager mergeManager, AbstractSession session) INTERNAL: This method will be called by a merging thread that is attempting to lock a new object that was not locked previously. Unlike the other methods within this class this method will lock only this object. -
attemptToAcquireLock
protected CacheKey attemptToAcquireLock(ClassDescriptor descriptor, Object primaryKey, AbstractSession session) INTERNAL: This method performs the operations of finding the cacheKey and locking it if possible. Returns True if the lock was acquired, false otherwise -
checkAndLockObject
protected CacheKey checkAndLockObject(Object objectToLock, Map lockedObjects, Map refreshedObjects, DatabaseMapping mapping, AbstractSession cloningSession) INTERNAL: Simply check that the object is not already locked then pass it on to the locking method -
releaseAllAcquiredLocks
INTERNAL: This method will release all acquired locks -
waitOnObjectLock
protected CacheKey waitOnObjectLock(ClassDescriptor descriptor, Object primaryKey, AbstractSession session, int waitTime) INTERNAL: This method performs the operations of finding the cacheKey and locking it if possible. Waits until the lock can be acquired -
getThreadToFailToAcquireCacheKeys
Getter forTHREAD_TO_FAIL_TO_ACQUIRE_CACHE_KEYS
-
getMapWriteLockManagerThreadToObjectIdsWithChangeSet
Getter forMAP_WRITE_LOCK_MANAGER_THREAD_TO_OBJECT_IDS_WITH_CHANGE_SET
-
clearMapThreadToObjectIdsWithChagenSet
Remove the current thread from the map of object ids with change sets that are about to bec ommited- Parameters:
thread
- the thread that is clearing itself out of the map of change sets it needs to merge into the shared cache
-
populateMapThreadToObjectIdsWithChagenSet
public static void populateMapThreadToObjectIdsWithChagenSet(Thread thread, Collection<ObjectChangeSet> objectChangeSets) Before a thread starts long wait loop to acquire write locks during a commit transaction the thread will record in this map the object ids it holds with chance sets. It will be useful information if a dead lock is taking place.- Parameters:
thread
- the thread that is in the middle of merge to the shared cache trying to acquire write locks to do this mergeobjectChangeSets
- the object change sets it has in its hands and that it would like to merge into the cache
-
clearMapWriteLockManagerToCacheKeysThatCouldNotBeAcquired
Before the problematic while loop starts we should always clear for this thread the set of cache keys it could not acquire.- Parameters:
thread
- the thread that what clear his set of cache keys it is struggling to acquire.
-
addCacheKeyToMapWriteLockManagerToCacheKeysThatCouldNotBeAcquired
public static void addCacheKeyToMapWriteLockManagerToCacheKeysThatCouldNotBeAcquired(Thread thread, ConcurrencyManager cacheKeyThatCouldNotBeAcquired, long whileStartDate) throws InterruptedException The thread was doing its while loop to acquire all required locks to proceed with the commmit and it realized there was one cache key it is unable to acquire- Parameters:
thread
- thread the thread working on updating the shared cachecacheKeyThatCouldNotBeAcquired
- the cache key it is not managing to acquire- Throws:
InterruptedException
- Should be fired because we are passing a flag into the determineIfReleaseDeferredLockAppearsToBeDeadLocked to say we do not want the thread to be blown up (e.g. we are afraid of breaking threads in the middle of a commit process could be quite dangerous). SeeALLOW_INTERRUPTED_EXCEPTION_TO_BE_FIRED_UP_FALSE
-
removeCacheKeyFromMapWriteLockManagerToCacheKeysThatCouldNotBeAcquired
public static void removeCacheKeyFromMapWriteLockManagerToCacheKeysThatCouldNotBeAcquired(Thread thread, ConcurrencyManager cacheKeyThatCouldNotBeAcquired) A cache keys was successfully acquired we want to make sure it is not recorded in the map of cache keys that could not be acquired. The situation theoretically can change. Failing to acquire a write lock can be a temporary situation. The lock might become available eventually. Otherwise there would be no point for the while loop that is trying to acquire these locks.- Parameters:
thread
- the thread that just managed to grab a write lockcacheKeyThatCouldNotBeAcquired
- the cache key it managed to acquire for writing.
-