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


  • 相关阅读:
    WIN10解决:失败 – 检测到病毒文件下载失败问题
    Jinja2学习
    div设置百分比高度 宽度
    flask静态html
    python排序之冒泡排序
    python中的break continue之用法
    python中的break continue用法
    python格式化输出(% format用法)
    python基础数据类型
    linux下anaconda使用教程
  • 原文地址:https://www.cnblogs.com/memoa/p/10059457.html
Copyright © 2011-2022 走看看