springcloud-redis 分布式锁

  走了很多弯路,查了很多资料。一开始看很多博客都是用luna脚本来写的。后面发现,那种方式无法使用。并不兼容。

  回归本源,整理一下,如何去做这个分布式锁;

  redis提供了一个很好的工具。setnx key value; 简单理解一下就是:如果不存在(if not exist),设置这个key-value键值对。所以我们可以以这种思路去加锁:

 循环{

if(set k-v) 退出循环;

else {休眠;}

}

代码实现如下:

@Autowired
    public RedisUtil(RedisTemplate redisTemplate,StringRedisTemplate stringRedisTemplate){
        this.redisTemplate = redisTemplate;
        this.operations = redisTemplate.opsForValue();

}

   public String setLock(String key)  {
            String uuid = UUID.randomUUID().toString();//用于释放锁
           boolean status =  false;
           try{
           while(true) {
                   status = operations.setIfAbsent("setnxkey", uuid);
                   if (status) {//获取到了锁
                       redisTemplate.expire(key, expire, TimeUnit.SECONDS);//设置超时时间
                       break;
                   } else {//获取锁失败的时候,判断一下是否没有超时时间,如果没有,那么可能这个是其他客户端获取的时候失败。加一个超时时间
                     long expiretemp  =  redisTemplate.getExpire(key);
                     if(expiretemp == -1)    redisTemplate.expire(key, expire, TimeUnit.SECONDS);//设置超时时间
                       Thread.sleep(expire);
                   }
           }}catch (Exception e){
                return "-1";
           }
//            operations.seti
            return uuid;
    }
释放锁:

public boolean releaseLock(String key,String uuid) {
    /**
     * 释放锁的时候,有可能因为持锁之后方法执行时间大于锁的有效期,此时有可能已经被另外一个线程持有锁,所以不能直接删除
     * 先判断一下当前持有锁的是否是当前的进程,如若不是,则放弃锁
     */
    String value = operations.get(key).toString();
    if(!value.equals(uuid)) return true;
    redisTemplate.delete(key);
    return false;
}

 

你可能感兴趣的:(java,springcloud,redis)