1. 程式人生 > >使用redis做分散式鎖

使用redis做分散式鎖

1、使用setnx命令。先看下官方文件http://redis.cn/commands/setnx.html

2、使用getset命令。先獲取,再set

 

實現案例:

  

 * create 2018-12-03 16:22
* <p>
* desc
**/
@Component
@Slf4j
public class RedisLock {

@Autowired
private StringRedisTemplate redisTemplate;

public boolean lock(String key,String timeout){
//在StringRedisTemplate中,setIfAbsent = setnx
//timeout = 當前時間 + 超時時間
if(redisTemplate.opsForValue().setIfAbsent(key,timeout)){
//能成功set則證明拿到了鎖
return true;
}

//假如key已經存在

String currentValue = redisTemplate.opsForValue().get(key);//獲取當前key的值

/**
* 此處為了防止死鎖
*/

//如果鎖過期
if(!StringUtils.isEmpty(currentValue) && Long.parseLong(currentValue) < System.currentTimeMillis()){
//獲取上一個鎖的時間
String oldValue = redisTemplate.opsForValue().getAndSet(key,timeout);

if(!StringUtils.isEmpty(oldValue) && oldValue.equals(currentValue)){
return true;
}
}
return false;
}

//解鎖
public void unlock (String key,String value){
String currentValue = redisTemplate.opsForValue().get(key);
try{
if(!StringUtils.isEmpty(currentValue) && currentValue.equals(value)){
redisTemplate.opsForValue().getOperations().delete(key);
}
}catch (Exception e){
log.error("解鎖異常,{}",e);
}
}
}


然後在需要加鎖的邏輯上,引用這個鎖方法即可
@Autowired
RedisLock redisLock ;


xxxx //業務邏輯

String time = System.currentTimeMillis()+10*1000;//超時10秒鐘

if(!redisLock.lock(key,time) ){
  //假如沒鎖上
  //丟擲異常
}

xxxxx //業務邏輯

//解鎖
redisLock.unlock(key,time);