INT-4105: RedisLock: Unlock Local in obtain()

JIRA: https://jira.spring.io/browse/INT-4105
Fixes GH-1888

The lock in Redis can be expired in between `obtain()` calls.
So, even if we return a new lock instance, the old one must clear properly.

* Add `lock.unlock()` to the `obtain()` if the case of expiration in Redis.
* Add `warn` for the exception on the `lock.unlock()`. We don't care about error here and just proceed to a new instance.

**Chery-pick to 4.3.x**

Remove the lock reference from `weakThreadLocks` as well
Add `registry.setUseWeakReferences(true);` to test-case

* Add assert for `lock.unlock()` in case of expiration

* Add `UUID.randomUUID()` for the registry key to avoid cross-talking during concurrent builds, e.g. on the CI server
https://build.spring.io/browse/INT-MASTER-352

This is actually a fix for the

JIRA: https://jira.spring.io/browse/INT-4083
This commit is contained in:
Artem Bilan
2016-09-02 13:21:20 -04:00
committed by Gary Russell
parent 763547562c
commit 450ac7f18d
2 changed files with 62 additions and 24 deletions

View File

@@ -259,7 +259,20 @@ public final class RedisLockRegistry implements LockRegistry {
if (lock != null && lock.thread != null) {
RedisLock lockInStore = this.redisTemplate.boundValueOps(this.registryKey + ":" + lockKey).get();
if (lockInStore == null || !lock.equals(lockInStore)) {
getHardThreadLocks().remove(lock);
try {
lock.unlock();
}
catch (Exception e) {
if (logger.isWarnEnabled()) {
logger.warn("Lock was released due to expiration. A new one will be obtained...", e);
}
}
if (this.hardThreadLocks.get() != null) {
this.hardThreadLocks.get().remove(lock);
}
if (this.weakThreadLocks.get() != null) {
this.weakThreadLocks.get().remove(lock);
}
lock = null;
}
}