Redis原理:setnx

setnx 命令的使用方式如下:

复制代码
SETNX key value

Set key to hold string value if key does not exist. In that case, it is equal to SET. When key already holds a value, no operation is performed. SETNX is short for "SET if N ot eXists".

中文:如果key不存在,则创建key,并设置相应的值

源码

复制代码
void setnxCommand(client *c) {
    c->argv[2] = tryObjectEncoding(c->argv[2]);
    // 调用通用的方法,并传递OBJ_SET_NX标号
    setGenericCommand(c,OBJ_SET_NX,c->argv[1],c->argv[2],NULL,0,shared.cone,shared.czero);
}

setGenericCommand 是一个通用方法,比较多的命令也都是通过该方法来处理的

复制代码
void setGenericCommand(client *c, int flags, robj *key, robj *val, robj *expire, int unit, robj *ok_reply, robj *abort_reply) {
    long long milliseconds = 0; /* initialized to avoid any harmness warning */
    int found = 0;
    int setkey_flags = 0;

    if (expire && getExpireMillisecondsOrReply(c, expire, flags, unit, &milliseconds) != C_OK) {
        return;
    }

    if (flags & OBJ_SET_GET) {
        if (getGenericCommand(c) == C_ERR) return;
    }
    // 按key进行查询
    found = (lookupKeyWrite(c->db,key) != NULL);
    // 如果是SetNx命令,并且找到,则直接返回
    if ((flags & OBJ_SET_NX && found) ||
        (flags & OBJ_SET_XX && !found))
    {
        if (!(flags & OBJ_SET_GET)) {
            addReply(c, abort_reply ? abort_reply : shared.null[c->resp]);
        }
        return;
    }

    setkey_flags |= (flags & OBJ_KEEPTTL) ? SETKEY_KEEPTTL : 0;
    setkey_flags |= found ? SETKEY_ALREADY_EXIST : SETKEY_DOESNT_EXIST;

    setKey(c,c->db,key,val,setkey_flags);
    server.dirty++;
    notifyKeyspaceEvent(NOTIFY_STRING,"set",key,c->db->id);

    .. 省略部分代码

    if (!(flags & OBJ_SET_GET)) {
        addReply(c, ok_reply ? ok_reply : shared.ok);
    }

    .. 省略部分代码
}

这里只看关于setnx相关的代码,其实也很简单,从数据库获取key对应的值,如果存在,则直接返回。

如果不存在,则通过setkey方法进行创建key。

在官方文档的setnx命令的开始,就有如下的说明

As of Redis version 2.6.12, this command is regarded as deprecated.

It can be replaced by SET with the NX argument when migrating or writing new code.

从2.6.12 开始,setnx 已经被标识为deprecated, 需要通过set 命令中,通过指定nx参数来替代。

复制代码
SET key value [NX | XX] [GET] [EX seconds | PX milliseconds |
  EXAT unix-time-seconds | PXAT unix-time-milliseconds | KEEPTTL]

set 命令将在下一节完整分析下。

相关推荐
用户3169353811835 天前
Java连接Redis
redis
小小工匠7 天前
Redis - 事务机制:能实现 ACID 属性吗
数据结构·redis·性能优化·并发·持久化
taocarts_bidfans7 天前
反向海淘跨境缓存架构优化:taocarts Redis分层缓存实战技术
redis·缓存·架构·反向海淘·taocarts
炘爚7 天前
Linux——Redis
数据库·redis·缓存
csjane10797 天前
Redisson 限流原理
java·redis
ThanksGive7 天前
Go 服务里的 Redis 锁惊群问题:一次本地合流优化实践
redis
小挪号底迪滴7 天前
Redis 和 MySQL 数据不一致怎么办?缓存更新策略实战
redis·mysql·缓存
闪电悠米7 天前
黑马点评-Redis ZSet-实现关注 Feed 流
服务器·网络·数据库·redis·缓存·junit·lua
Devin~Y7 天前
大厂 Java 面试实录:从音视频内容社区到 AI RAG 的全链路技术设计
java·spring boot·redis·spring cloud·微服务·kafka·音视频