Redis

关注公众号 jb51net

关闭
首页 > 数据库 > Redis > Redis SETNX

Redis SETNX的实现示例

作者:飞滕人生TYF

SETNX是Redis提供的原子操作,用于在指定键不存在时设置键值,并返回操作结果,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

SETNX 是 Redis 提供的一种原子操作,全称是 “SET if Not eXists”,用于在指定的键不存在时设置键值,并返回操作结果。它是实现分布式锁幂等性控制的核心工具之一。

1. SETNX 的基本功能

语法

SETNX key value

返回值

使用示例

SETNX lock_key "123"

执行结果

2. SETNX 的特性

3. 结合 EXPIRE 的分布式锁

SETNX 本身不能设置过期时间,因此为了避免死锁问题(如客户端异常未释放锁),可以结合 EXPIRE 设置锁的自动过期时间。

问题

解决方案 1:SETNX + EXPIRE

if redis.call("SETNX", KEYS[1], ARGV[1]) == 1 then
    redis.call("EXPIRE", KEYS[1], ARGV[2])
    return 1
else
    return 0
end

缺点

解决方案 2:SETNX 改用 SET(推荐)

Redis 提供了改进版本的 SET 命令,可以直接设置键值并附加过期时间:

SET key value NX EX seconds

示例

SET lock_key "123" NX EX 10

优点

4. 使用 SETNX 实现分布式锁

SETNX 的一个典型应用是分布式锁,保证在分布式系统中对共享资源的互斥访问。

4.1 基本实现

实现逻辑

String lockKey = "lock_key";
String requestId = UUID.randomUUID().toString();
int expireTime = 10;

// 获取锁
if (redisTemplate.opsForValue().setIfAbsent(lockKey, requestId, expireTime, TimeUnit.SECONDS)) {
    try {
        // 处理业务逻辑
    } finally {
        // 释放锁
        if (requestId.equals(redisTemplate.opsForValue().get(lockKey))) {
            redisTemplate.delete(lockKey);
        }
    }
} else {
    // 获取锁失败
    System.out.println("Lock is already held by another process.");
}

4.2 Lua 脚本保证原子性

为了确保释放锁的操作是原子的,可以使用 Lua 脚本完成判断和删除:

if redis.call("get", KEYS[1]) == ARGV[1] then
    return redis.call("del", KEYS[1])
else
    return 0
end

调用示例

String script = "if redis.call('get', KEYS[1]) == ARGV[1] then " +
                "return redis.call('del', KEYS[1]) " +
                "else return 0 end";
redisTemplate.execute(new DefaultRedisScript<>(script, Long.class), 
                      Collections.singletonList(lockKey), requestId);

5. SETNX 的典型应用场景

5.1 分布式锁

5.2 请求去重

5.3 幂等性控制

6. SETNX 的优缺点

优点缺点
原子性强,适合高并发场景无法直接设置过期时间
实现简单,易于集成到业务逻辑中需要结合 EXPIRE 或改用 SET 命令
性能高,Redis 本身支持高吞吐量需要额外处理死锁或锁释放的边界条件

7. SETNX 的改进建议

8. 总结

到此这篇关于Redis SETNX的实现示例的文章就介绍到这了,更多相关Redis SETNX内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文