setnx分布式锁实战
时间: 2025-02-05 07:04:44 浏览: 51
### 使用 `SETNX` 实现分布式锁
#### SETNX 基本原理
`SETNX` 是 Redis 提供的一个命令,全称为 "SET if Not eXists"。该命令用于设置键值对,仅当指定的键不存在时才会成功执行。这一特性使得 `SETNX` 成为了实现简单版本控制以及构建分布式锁的基础[^1]。
#### 实战案例:使用 `SETNX` 创建分布式锁
下面是一个利用 `SETNX` 来创建分布式锁的具体例子:
```java
public class DistributedLock {
private final Jedis jedis;
private static final String LOCK_SUCCESS = "OK";
private static final Long RELEASE_SUCCESS = 1L;
public boolean tryGetDistributedLock(String lockKey, String requestId, int expireTime) {
String result = jedis.set(lockKey, requestId, "NX", "PX", expireTime);
return LOCK_SUCCESS.equals(result);
}
public void releaseDistributedLock(String lockKey, String requestId) {
String script =
"if redis.call('get', KEYS[1]) == ARGV[1] then "
+ "return redis.call('del', KEYS[1]) "
+ "else "
+ "return 0 end";
Object result = jedis.eval(script, Collections.singletonList(lockKey), Collections.singletonList(requestId));
if (!(RELEASE_SUCCESS.equals(result))) {
throw new RuntimeException("解锁失败");
}
}
}
```
这段代码展示了如何通过 Java 和 Jedis 客户端库来操作 Redis 的 `SETNX` 功能,从而安全地获取和释放分布式锁。这里的关键在于不仅设置了唯一的请求 ID 还指定了过期时间以防止死锁的发生[^3]。
#### 注意事项
- **唯一标识符**:每次尝试获得锁的时候都应该传递一个独一无二的字符串作为参数(即上面提到的 `requestId`),这样可以在删除锁之前验证当前线程确实是持有者。
- **自动失效机制**:为了避免因程序崩溃而导致永久占用资源的情况发生,在调用 `SETNX` 设置锁的同时应该附加一个合理的 TTL 参数让其能够在一定时间内自行消失。
- **加锁与解锁的安全性**:确保只有真正拥有锁的应用才能解除它;这通常涉及到 Lua 脚本来保证原子性的检查并移除操作。
- **重试逻辑**:考虑到网络延迟等因素的影响,应用程序应当具备一定的重试策略去处理偶尔发生的竞争条件问题。
阅读全文
相关推荐




















