Redis 分布式锁

/**
 * 加锁(并发不保证原子性)
 * @param key
 * @param value 当前时间+超时时间
 * @return
 */
public boolean lock(String key, String value , StringReidsTemplate redisTemplate) {
        if(redisTemplate.opsForValue().setIfAbsent(key, value)) {
            return true;
        }  
        String currentValue = redisTemplate.opsForValue().get(key);
        //如果锁过期
        if (!StringUtils.isEmpty(currentValue) && Long.parseLong(currentValue) < System.currentTimeMillis()) {
            //获取上一个锁的时间
            String oldValue = redisTemplate.opsForValue().getAndSet(key, value);
            if (!StringUtils.isEmpty(oldValue) && oldValue.equals(currentValue)) {
                return true;
            }
        }
    return false;
}
/**
 * 解锁
 * @param key
 * @param value
 */
public void unlock(String key, String value , StringRedisTemplate redisTemplate) {
    try {
        String currentValue = redisTemplate.opsForValue().get(key);
        if (!StringUtils.isEmpty(currentValue) && currentValue.equals(value)) {
            redisTemplate.opsForValue().getOperations().delete(key);
        }
    }catch (Exception e) {
        log.error("【redis分布式锁】解锁异常, {}", e);
    }
}

/** 
* 加锁(并发保证原子性)
* @param key 
* @param value 
*/
public static boolean lockByTransaction(String lockKey , String value , StringRedisTemplate redis) {
   redis.setEnableTransactionSupport(true);
       SessionCallback sessionCallback = new SessionCallback() {
           List exec = null;
           @Override
           @SuppressWarnings("unchecked")
           public Boolean execute(RedisOperations operations) throws DataAccessException {
               operations.multi();
               redis.opsForValue().setIfAbsent(lockKey , value);
               redis.expire(lockKey, 5 , TimeUnit.SECONDS);
               exec = operations.exec();
               if(exec.size() > 0) {
                   return (Boolean) exec.get(0);
               }
               return false;
           }
       };
       return redis.execute(sessionCallback);
}
String timestamp = String.valueOf(System.currentTimeMillis() + 5 * 1000L);
lock("redisKey" , timestamp , redisUtil.getStringRedisTemplate()); 
  

 

你可能感兴趣的:(技术)