springcloud-redis 分布式锁

Redis分布式锁实践
本文深入探讨了使用Redis实现分布式锁的详细过程。通过分析luna脚本的局限性,提出了利用setnx指令进行锁的获取与释放的方法。文章提供了具体的Java代码实现,包括锁的获取、设置超时时间和释放锁的完整流程。

  走了很多弯路,查了很多资料。一开始看很多博客都是用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;
}

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值