Redisson concurrent locking may occasionally cause one of the threads to acquire a timeout, resulting in lock failure
Expected behavior
Concurrent locking theoretically means that after one thread locks and releases the lock, another thread should be able to acquire the lock
Actual behavior
The phenomenon we see now is that after one thread in production locked and released, another thread did not acquire the lock (occasionally)
Steps to reproduce or test case
In the tryLock (long waitTime, long leaseTime, TimeUnit) method of redisson, is there a situation where the semaphore for the first thread to release the lock has been issued, but the other thread has not yet established a subscription relationship, resulting in the following logic not waiting for notification?
...... current = System.currentTimeMillis(); CompletableFuture<RedissonLockEntry> subscribeFuture = subscribe(threadId); try { subscribeFuture.get(time, TimeUnit.MILLISECONDS); } catch (TimeoutException e) { .......
Redis version
5.0
Redisson version
3.17.6 & 3.19.3
Redisson configuration
Make sure that it's not the same thread. Since the lock is reentrant.
Make sure that it's not the same thread. Since the lock is reentrant.
Not the same thread, because two concurrent requests are sent to different nodes, it is impossible to have the same thread. Moreover, if it is the same thread, due to reentrancy, my second request should not have a lock timeout.
is there a situation where the semaphore for the first thread to release the lock has been issued, but the other thread has not yet established a subscription relationship, resulting in the following logic not waiting for notification?
No, since a new attempt is made right after subscription.
My question is that before the second thread subscribes, the first thread has already released the lock and published the event of releasing the lock. Will the second thread not receive notification of releasing the lock in the following code, resulting in continuous blocking?
CompletableFuture<RedissonLockEntry> subscribeFuture = subscribe(threadId);
If it's subscribed after the event was published then it won't get a notification. I don't see the reason of continuous blocking here.
Perhaps it's not the reason for this code. Today, we tested in a testing environment and applied for locks on 10000 locks simultaneously within one minute, with each lock being applied for four times by different threads. In this scenario, it is common for some threads to acquire locks and timeout every time. Is it normal for lock timeout to occur in this concurrency scenario? We use write locks.
Our locking code is roughly like this:
RLock lock = redissonClient.getReadWriteLock(key).writeLock(); boolean lockSuccess = lock.tryLock(waitTime, LEASE_TIME, TimeUnit.MILLISECONDS);
If it's subscribed after the event was published then it won't get a notification. I don't see the reason of continuous blocking here. Another phenomenon is that the log I printed when the thread failed to obtain a lock timeout is as follows: "lock fail! lock name:group_lock:123, isLocked:false, getHoldCount:0, isHeldByCurrentThread:false,remainTimeToLive:-2" From the logs, it can be seen that the lock to be applied for at that time was not locked by other threads, but it could not be obtained. It felt like the signal had been lost somewhere, causing it to be unable to apply the lock.
I also encountered this problem, how was it solved in the end, looking forward to your reply