/**
* Redis分布式锁
* @author 向振华
* @date 2018/11/28 13:18
*/
@Component
public class RedisLock {
@Resource
private StringRedisTemplate redisTemplate;
/**
* 加锁
* @param key
* @param value 当前时间+超时时间
* @return
*/
public boolean lock(String key, String value) {
//SETNX命令, 不存在则SET,存在则不处理
if (redisTemplate.opsForValue().setIfAbsent(key, value)) {
return true;
}
String currentValue = redisTemplate.opsForValue().get(key);
//如果锁过期
if (StringUtils.isEmpty(currentValue) && (Long.parseLong(currentValue) < System.currentTimeMillis())) {
//GETSET命令, 自动将key对应到value并且返回原来key对应的value,(获取上一个锁的时间)
String oldValue = redisTemplate.opsForValue().getAndSet(key, value);
if (!StringUtils.isEmpty(oldValue) && oldValue.equals(value)) {
return true;
}
}
return false;
}
/**
* 解锁
* @param key
* @param value
*/
public void unLock(String key, String value) {
try {
String currentValue = redisTemplate.opsForValue().get(key);
if (!StringUtils.isEmpty(currentValue) && currentValue.equals(value)) {
redisTemplate.opsForValue().getOperations().delete(key);
}
} catch (Throwable e) {
throw new RuntimeException("解锁异常!");
}
}
}
测试
public String test(String key){
//加锁
long time = System.currentTimeMillis() + TIMEOUT;
if(!redisLock.lock(key, String.valueOf(time))) {
throw new RuntimeException( "请求频繁~");
}
//...
//解锁
redisLock.unLock(key, String.valueOf(time));
return "S";
}