Hardy
Hardy

Reputation: 23

Redis's Redisson's API method .unlock() is not releasing the lock, trying from the same instance

I have created singleton redisson instance in my Java application, which I am using to communicate to redis servers. Now using this redisson instance, I am acquiring a lock which after getting some task done, I am releasing. But after calling unlock method, I still see redis have the lock and other threads are unable to acquire the lock. Below is the code snippet, I am using:

class RedisInstance
{
   static RedisInstance ins;
   private RedisInstance()
     {
       ins = new RedisInstance();
     }
   public static RedisInstance getInstance()
     {
       return ins;
     }
   //Acquire the lock:   
   public boolean acquireLock(String lockKey)
     {
         RLock redisLock = getRedisClient().getLock(lockKey);
         boolean isLockFree;
         try 
         {
            isLockFree = redisLock.tryLock(lockAcquistionTimeLimit, TimeUnit.SECONDS);
            if(isLockFree)
            {
                 redisLock.lock();
                 logger.info("lock acquired for: {}", lockKey);
                 return true;
            }
         } 
         catch (InterruptedException e) 
         {
             logger.error("Got exception {} in acquiring Redis Lock for: {}" , e, lockKey);
         }
         
         return false;
     }


   //Release the lock:
   public void unlock(String lockKey)
     {
         RLock redisLock = getRedisClient().getLock(lockKey);
         redisLock.unlock();
         logger.debug("IS redis locked "+redisLock.isLocked());
         logger.info("lock released for: {}", lockKey);
     }
}
class A
{
   RedisIns ins = RedisInstance.getInstance();
   public void run() 
        {
        if(ins.acquireLock(lockKey))
                {
                    try 
                    {
                        //do some processing takes less than a second       
                    }
                    catch(Exception e)
                    {
                        
                    }
                    finally
                    {
                        ins.unlock(lockKey);
                    }
                }
         }
   //In my main method:
   public static void main(String args[])
   {
     A a = new A();
     A b = new A();
     Thread t1 = new Thread(a);
     Thread t2 = new Thread(b);
     t1.start();
     Thread.sleep(5000); //just to mock, lets say t1 finishes before t2 starts
     t2.start();
   }
}

After t1 calls ins.unlock(lockKey);, the log logger.debug("IS redis locked "+redisLock.isLocked()); says: true and t2 is unable to acquire the lock.

But if I replace redisLock.unlock(); with redisLock.forceUnlock(); everything is working as expected. Dont know why unlock() is unable to release the lock forceUnlock() is able to do it.

Upvotes: 2

Views: 2179

Answers (1)

user3679868
user3679868

Reputation: 693

tryLock returns true if it acquired the lock. So calling lock after is unnecessary, and I think it may be the cause of your problem. The implementation probably expects an even number of lock/unlock and in you case you have one more lock than unlock.

Upvotes: 1

Related Questions