应对高并发场景的redis加锁技巧

// 获取锁
getLock() {
    // 是否有正在执行的线程
    boolean hasLock = false;
    try {
        hasLock = redisClient.setnx("lockKey", "ing") == 1;
        if (hasLock) {
            redisClient.expire("lockKey", 60*60);//一小时
        }
    } catch (Exception e) {
        logger.error("redis.lock.setnx is error", e);
        // 避免成功获取到锁,但是未成功设置过期时间
        redisClient.expire("lockKey", 60*60);//一小时
    }
    
    reutrn hasLock;
}

//释放锁
releaseLock() {
    redisClient.del("lockKey");
}

//调用入口
doMethod() {
    if(!getLock()) {
        //未获取到锁
        return "不允许调用";
    }

    //获取到锁,开始处理
    try{
        //业务逻辑执行

        return "处理成功";
    } finally {
        // 只要获取到锁,则在业务逻辑结束之后,必须释放锁
        releaseLock();
    }

    return "异常";
}

 

redisClient.setnx 时,将value设置为某个时间戳,然后可以通过一个job去定时校验是否需要释放该锁,或者在getLock之前加一步操作,get("lockKey")到时间戳,检查是否需要释放锁,然后del("lockkey")

posted @ 2019-06-05 15:37  那些年的代码  阅读(958)  评论(0编辑  收藏  举报