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


  • 相关阅读:
    day34
    day33 UDP、进程
    Java RMI 框架(远程方法调用)
    Maven查看JAR包的依赖关系
    连接Oracle数据库的时候报了“Got minus one from a read call”
    Http、Socket和WebService协议之间的区别
    http 协议
    其它
    Jmeter-CSV data set config参数化
    英文
  • 原文地址:https://www.cnblogs.com/memoa/p/10059457.html
Copyright © 2011-2022 走看看