使用redis的分布式锁,我们首先想到的可能是setNx
命令。
if (jedis.setnx(lockKey, val) == 1) {
jedis.expire(lockKey, timeout);
}
容易,三下五除二,就可以把代码写好。
这段代码确实可以加锁成功,但你有没有发现什么问题?
加锁操作
和后面的设置超时时间
是分开的,并非原子操作
。
假如加锁成功,但是设置超时时间失败了,该lockKey就变成永不失效。假如在高并发场景中,有大量的lockKey加锁成功了,但不会失效,有可能直接导致redis内存空间不足。
那么,有没有保证原子性的加锁命令呢?
答案是:有,请看下面。
上面说到使用setNx
命令加锁操作和设置超时时间是分开的,并非原子操作。
而在redis中还有set
命令,该命令可以指定多个参数。
String result = jedis.set(lockKey, requestId, "NX", "PX", expireTime);
if ("OK".equals(result)) {
return true;
}
return false;
其中:
lockKey
:锁的标识