Redis嘿嘿嘿

查询缓存

  1. springboot启动类不要忘记@Enablecaching注解
  2. Controller查询操作, @Cacheable(cacheNames=’’,key=’’), 查询方法返回的对象要能序列化
  3. 更新或者删除缓存@CachePut(cacheNames=’’,key=’’),更新缓存数据
    @CacheEvict(cacheNames = “”),清除缓存
  4. key如果不填,默认为方法的参数. 类上配置@cacheconfig(cacheNames=’’),方法上可以省略cachename配置
  5. key可以对应方法的参数, condition 缓存的条件, unless 不缓存的条件(#result代表返回值)
    1
    2
    3
    4
    5
    @GetMapping("/list")
    @Cacheable(cacheNames="product",key="#id",condition="#id.length>0",unless="#result.getCode()!=200")
    public Result list(@RequestParam("id) int id){
    return xxxxx;
    }

发布订阅

好处: 无需集成额外的消息中间件. 功能应该能够满足小项目需求,性能也不错. 个人不太喜欢用,还是倾向于MQ

初探分布式缓存锁

setnx key value—>key不存在时设置值

getset key value—>先get旧值, 然后set新值

  1. 加锁()

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    /**
    *key xxx
    *value 当前时间+超时时间(例:2s)
    */
    public boolean lock(String key, String value){
    if(redisTemplate.opsForValue().setIfAbsent(key,value)){
    return true;//key不存在, 设置value成功, 拿到了锁
    }
    //Thread---A, Thread---B
    String lastValue=redisTemplate.opsForValue().get(key);

    //锁已经过期了, 其它线程才可以继续抢
    if(!StringUtils.isEmpty(lastValue)&&Long.parseLong(lastValue)<System.currentTimeMillis()){
    // A,B线程抢占cpu执行
    String oldValue=redisTemplate.opsForValue().setIfAbsent(key,value);
    //A线程先执行, 获取的是之前的值 oldValue==lastValue,并设置了新的值(当前时间+超时时间)
    //B线程又执行, 获得的是A线程设置的新值oldValue!=lastValue

    if(!StringUtils.isEmpty(oldValue)&&oldValue.equals(lastValue)){//只有A线程的oldValue==lastValue
    return true; //A线程拿到了锁
    }
    }

    return false;
    }
  2. 解锁

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    /**
    *key xxx
    *value 拿到锁的线程: 拿到锁那一时刻的时间+超时时间(2s)
    */
    public boolean unlock(String key, String value){
    try{
    String time = redisTemplate.opsForValue().get(key);
    //线程A拿到锁后执行了一堆操作...
    //此时要解锁, 那么正常情况下,此时redis里的time==A拿锁时设置的时间value
    if(!StringUtils.isEmpty(time)&&time.equals(value)){
    redisTemplate.opsForValue().getOperations().delete(key);//释放A线程的锁
    }

    }catch(Exception e){
    log.error(".....")
    }
    }

本文标题:Redis嘿嘿嘿

文章作者:啪啪啪的指针

发布时间:2018年08月24日 - 18:08

最后更新:2018年08月30日 - 16:08

原始链接:https://www.bootvue.com/2018/08/24/Redis/

转载说明: 转载请保留原文链接及作者。