通过双key解决缓存并发问题

2020/05/27 22:00
阅读数 224
public static boolean set(String key, String value, int seconds) {
    Jedis jedis = null;
    try {
        jedis = jedisPool.getResource();
        if (seconds > 0){
            // 添加数据缓存,缓存有效时间 = 真实时间 + 1 天
            jedis.set(key, seconds + 60 * 60 * 24, value);

            // 添加过期时间缓存,缓存有效时间 = 真实时间
            jedis.set("lock_" + key, seconds, System.currentTimeMillis() + "");
        } else {
            jedis.set(key, value);
            jedis.set("lock_" + key, System.currentTimeMillis() + "");
         }

         return true;
    } catch (JedisException e) {
         if (jedis != null) {
             returnBrokenResource(jedis);
             jedis = null;
         }
         throw e;
    } finally {
         if (jedis != null) {
             returnResource(jedis);
         }
    }
}

public static String get(String key) {
    Jedis jedis = null;
    try {
        jedis = jedisPool.getResource();

        // 缓存过期 && 获取锁成功,setnx:原子操作
        if (jedis.setnx("lock_" + key, System.currentTimeMillis() + "") == 1) {
            /**
             * 将锁的失效时间设为60s,在60s内若查询数据库成功,则更新锁的失效时间=缓存时间
             * 如果60s内出现异常,则60s后第一个请求又会去访问数据库
             * 返回null表示没有查询到数据库,外层代码会通过数据库获取数据并设置缓存
             */
            jedis.expire("lock_" + key, 60);
            return null;
        } else{
            // 缓存未过期或者缓存过期但获取锁失败, 则返回旧数据
            return jedis.get(key);
        }
    } catch (JedisException e) {
        if (jedis != null) {
            returnBrokenResource(jedis);
            jedis = null;
        } 
        throw e;
    } finally {
        if (jedis != null) {
            returnResource(jedis);
        }
    }
}

 

展开阅读全文
加载中

作者的其它热门文章

打赏
0
0 收藏
分享
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部