在某次某街面试中,面试官问:能否使用redis INCR命令是否可以实现分布式锁?
正确的使用方式https://blog.youkuaiyun.com/weixin_38336658/article/details/85786818
incr 方法会导致什么问题?
当你template.opsForValue(),increment(key,1);这个key就存在了,如果忽然redis宕机,那么这个key一直存在。
为啥说我上面链接是正确解法?
经过本人思考,道理都是同一个,就是如果redis宕机,你这个key是存在的,其他客户端是获取不到的,那么会导致死锁。
使用redis set()含时间参数的也一样,为了可以在特定时间内,让锁失效.
String result=jedis.set(lockKey, requestid, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, expireTime);
incr方法
如果incr方法后不是为1,则让key 2秒失效
redisTemplate.expire(key, 2, TimeUnit.SECONDS);
这种方法还是不推荐,看下别人的代码分析一下
@Autowired
private RedisTemplate redisTemplate;
/**
* 加锁
*/
public boolean getLock(String key) {
try {
long count = redisTemplate.opsForValue().increment(key, 1);
if(count == 1){
//设置有效期2秒
redisTemplate.expire(key, 2, TimeUnit.SECONDS);
return true;
}else{
long time = redisTemplate.getExpire(key,TimeUnit.SECONDS);
if(time == -1){
//设置失败重新设置过期时间
redisTemplate.expire(key, 2, TimeUnit.SECONDS);
return true;
}
}
//如果存在表示重复
return false;
} catch (Exception e) {
logger.error("redis加锁异常", e);
redisTemplate.delete(key); //出现异常删除锁
return true;
}
}
如果在redisTemplate.expire(key, 2, TimeUnit.SECONDS);这里redis宕机了,key失效不了的。还是会导致死锁
没有jedis.set(lockKey, requestid, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, expireTime);这种好,因为它设置的时候就已经把key以及过期时间设置进去了。