@Override
 protected void lockEntry(
     PersistentEntity persistentEntity, String entityFamily, Serializable id, int timeout) {
   String redisKey = getRedisKey(entityFamily, id);
   final TimeUnit milliUnit = TimeUnit.MILLISECONDS;
   final long waitTime = TimeUnit.SECONDS.toMillis(timeout);
   final String lockName = lockName(redisKey);
   int sleepTime = 0;
   while (true) {
     if (redisTemplate.setnx(lockName, System.currentTimeMillis())
         && redisTemplate.expire(lockName, timeout)) {
       break;
     } else {
       if (redisTemplate.ttl(lockName) > 0) {
         try {
           if (sleepTime > waitTime) {
             throw new CannotAcquireLockException(
                 "Failed to acquire lock on key [" + redisKey + "]. Wait time exceeded timeout.");
           } else {
             // wait for previous lock to expire
             sleepTime += 500;
             milliUnit.sleep(500);
           }
         } catch (InterruptedException e) {
           throw new CannotAcquireLockException(
               "Failed to acquire lock on key [" + redisKey + "]: " + e.getMessage(), e);
         }
       } else {
         if (redisTemplate.getset(lockName, System.currentTimeMillis()) != null
             && redisTemplate.expire(lockName, timeout)) break;
       }
     }
   }
 }