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<Boolean> sessionCallback = new SessionCallback<Boolean>() {
           List<Object> 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());

//正确加锁

public static boolean lockByNX(String lockKey, RedisTemplate redis) {
    String lock = LOCK_PREFIX + lockKey;
    return (boolean) redis.execute((RedisCallback<Object>) redisConnection -> {
        String expireAt = String.valueOf(System.currentTimeMillis() + LOCK_EXPIRE + 1);
        Boolean nx = redisConnection.setNX(lock.getBytes(), expireAt.getBytes());
        if (nx) {
            return true;
        } else {
            byte[] bytes = redisConnection.get(lock.getBytes());
            if (Objects.nonNull(bytes) && bytes.length > 0) {
                long expireTime = Long.parseLong(new String(bytes));
                if (expireTime < System.currentTimeMillis()) {
                    byte[] oldValue = redisConnection.getSet(lock.getBytes(),    String.valueOf(System.currentTimeMillis() + LOCK_EXPIRE + 1).getBytes());
                    return Long.parseLong(new String(oldValue)) < System.currentTimeMillis();
                }
            }
        }
        return false;
    });
}

public static void unlockByNX(String key, RedisTemplate redis) {
    redis.delete(key);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值