Redis 分布式锁

Posted dikeboy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Redis 分布式锁相关的知识,希望对你有一定的参考价值。

 public Object lock(String cacheKey,Type type) 
		Object cacheValue= getCacheValue(cacheKey,type);
		if(cacheValue!=null) 
			return cacheValue;
		//如果已存在缓存,则直接取
		 String lockKey ="lock_"+cacheKey;
	   boolean success = lettuceTemplate.opsForValue().setIfAbsent(lockKey, "1",20,TimeUnit.SECONDS);//seIfAbsent,如果不存在则设置,返回,true,否则false,这里设置了20秒过期时间,为了避免死锁
		try 
			while(!success) 
				cacheValue= getCacheValue(cacheKey,type);
				if(cacheValue!=null) 
					lettuceTemplate.delete(lockKey);
					return cacheValue;
				
				success = lettuceTemplate.opsForValue().setIfAbsent(lockKey, "1",20,TimeUnit.SECONDS);
				Thread.sleep(50);
              //每隔50秒,判断缓存数据是否存在,存在则直接返回,并且主动删除锁key
			
			if(success) 
				cacheValue= getCacheValue(cacheKey,type);
				if(cacheValue!=null) 
					lettuceTemplate.delete(lockKey);
					return cacheValue;
				
				return null;
			 //lockKey释放,说明已经存在缓存,直接取
		 catch (Exception e) 
			// TODO Auto-generated catch block
			e.printStackTrace();
		
		return null;
   

  Type 的话是gson的类型,为了实体跟String相互转换,cahekey对应的缓存key

 public Object getCacheValue(String key,Type type) 
       if(isCache) 
           String value =  lettuceTemplate.opsForValue().get(key);

           if(value!=null) 
               return gson.fromJson(value, type);
           
       
       return null;
   

   public void putCacheValue(String key, Object value,int cacheTime) 
       if(value!=null&&isCache) 
           if(cacheTime==0) 
               lettuceTemplate.opsForValue().set(key, gson.toJson(value));;
           
           else 
               lettuceTemplate.opsForValue().set(key, gson.toJson(value),cacheTime,TimeUnit.SECONDS);
           
       
   

调用的地方

    public ResponseEntity getTypes() 
        String cacheKey = getCacheKey("type");
        Type type = new TypeToken <List<TypeEntity>> ()  .getType();
         Object cacheValue = lock(cacheKey, type);
         if(cacheValue==null)  
             List<TypeEntity> lists =mRomManager.getTypes();
            putCacheValue(cacheKey,lists,0);
            return new ResponseEntity(lists);
        
        else 
            return new ResponseEntity(cacheValue);
        
    //调用的地方, 因为有些缓存需要根据分页做不同的策略,如果简单的话用AOP 切所有接口 会简化很多

 

以上是关于Redis 分布式锁的主要内容,如果未能解决你的问题,请参考以下文章

分布式锁三种解决方案

分布式锁Redis分布式锁注解灵活实现

分布式Redis锁并发编程Redis分布式锁实例

Redis进阶学习03---Redis完成秒杀和Redis分布式锁的应用

间谍高度(上帝视角)和redis分布式锁

分布式锁,及Redis实现分布式锁