Redis 锁 实例

217 阅读1分钟

终于啊,我的朋友找到我。

场景是这样的,系统需要调用统一认证系统获取clientToken,多个微服务使用同一个clientId,生成的clientToken三十分钟有效,同一时间只有一个clientToken有效,每次调用都会产生一个新的clientToken,前一个失效。

这种场景下,要锁了吧,必须锁吧,我认为必须锁。

锁加在了生成token时。代码如下:

public GenerateTokenResp generateClientToken() throws RestClientException, ServiceCommonBusinessException {   
    //先从redis中取token
    GenerateTokenResp clientToken = getGenerateTokenRespFromRedis();    
    if (!ObjectUtils.isEmpty(clientToken)){        
        return clientToken;   
    } 
    //没有???加锁获取存储   
    storeClientToken();    
    return getGenerateTokenRespFromRedis();
}

private GenerateTokenResp getGenerateTokenRespFromRedis(){    
    Object object = redisTemplate.opsForValue().get(BaseConstant.CLIENT_TOKEN_KEY);    
    if (null != object){        
        return JSONObject.parseObject(String.valueOf(object),GenerateTokenResp.class);    
     }    
     return null;
}

public void storeClientToken(){ 
    //自旋,跟jdk学的,感觉没毛病   
    for (;;){     
    //先看有没有,万一有了呢,别旋了得停了   
    if (!ObjectUtils.isEmpty(getGenerateTokenRespFromRedis())){           
        return;        
    }
    //获取锁,(NX键不存在  XX键存在 )(PX毫秒 EX秒)           String result = redisTemplate.execute((RedisCallback<String>) connection -> {            
    JedisCommands commands = (JedisCommands) connection.getNativeConnection();           
    return commands.set(BasemConstant.CLIENT_TOKEN_LOCK_KEY, "locked", "NX", "PX", BaseConstant.CLIENT_TOKEN_LOCK_SAFE);        
});        
if ("OK".equals(result)){  
    //拿到锁了          
    try {                
        //调用接口获取token
        GenerateTokenResp clientToken = getClientToken();   
        //成功存起来             
        redisTemplate.opsForValue().set(BaseConstant.CLIENT_TOKEN_KEY,JSONObject.toJSONString(clientToken),BaseConstant.CLIENT_TOKEN_SAFE, TimeUnit.MINUTES);               
        return;            
     } catch (RestClientException | ServiceCommonBusinessException e) {      
          //失败释放锁          
          redisTemplate.delete(BaseConstant.CLIENT_TOKEN_LOCK_KEY);            
     }        
 }    
}}

朋友啊朋友,看起来应该没有问题对不对,感觉逻辑上也说的过去。