zoukankan      html  css  js  c++  java
  • 使用redis做分布式锁

    1、使用setnx命令。先看下官方文档http://redis.cn/commands/setnx.html

    2、使用getset命令。先获取,再set

    实现案例:

      

     * create 2018-12-03 16:22
    * <p>
    * desc
    **/
    @Component
    @Slf4j
    public class RedisLock {

    @Autowired
    private StringRedisTemplate redisTemplate;

    public boolean lock(String key,String timeout){
    //在StringRedisTemplate中,setIfAbsent = setnx
    //timeout = 当前时间 + 超时时间
    if(redisTemplate.opsForValue().setIfAbsent(key,timeout)){
    //能成功set则证明拿到了锁
    return true;
    }

    //假如key已经存在

    String currentValue = redisTemplate.opsForValue().get(key);//获取当前key的值

    /**
    * 此处为了防止死锁
    */

    //如果锁过期
    if(!StringUtils.isEmpty(currentValue) && Long.parseLong(currentValue) < System.currentTimeMillis()){
    //获取上一个锁的时间
    String oldValue = redisTemplate.opsForValue().getAndSet(key,timeout);

    if(!StringUtils.isEmpty(oldValue) && oldValue.equals(currentValue)){
    return true;
    }
    }
    return false;
    }

    //解锁
    public void unlock (String key,String value){
    String currentValue = redisTemplate.opsForValue().get(key);
    try{
    if(!StringUtils.isEmpty(currentValue) && currentValue.equals(value)){
    redisTemplate.opsForValue().getOperations().delete(key);
    }
    }catch (Exception e){
    log.error("解锁异常,{}",e);
    }
    }
    }


    然后在需要加锁的逻辑上,引用这个锁方法即可
    @Autowired
    RedisLock redisLock ;


    xxxx //业务逻辑

    String time = System.currentTimeMillis()+10*1000;//超时10秒钟

    if(!redisLock.lock(key,time) ){
      //假如没锁上
      //抛出异常
    }

    xxxxx //业务逻辑

    //解锁
    redisLock.unlock(key,time);


    其他方案可参考:
    http://www.cnblogs.com/seesun2012/p/9214653.html


  • 相关阅读:
    SQL的join使用图解
    归并排序的JAVA实现
    java 快速排序 时间复杂度 空间复杂度 稳定性
    哈希表(HashMap)分析及实现(JAVA)
    外部排序
    海量数据面试题整理
    《CSS3秘籍》第6、7章
    《CSS3秘籍》第3-5章
    《CSS3秘籍》第1、2章
    《HTML5与CSS3基础教程》第11、14-16、18章
  • 原文地址:https://www.cnblogs.com/memoa/p/10059457.html
Copyright © 2011-2022 走看看