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 命令将在下一节完整分析下。

相关推荐
呼拉拉呼拉2 小时前
Redis故障转移
数据库·redis·缓存·高可用架构
什么都想学的阿超2 小时前
【Redis系列 04】Redis高可用架构实战:主从复制与哨兵模式从零到生产
数据库·redis·架构
我命由我123454 小时前
Spring Boot 项目集成 Redis 问题:RedisTemplate 多余空格问题
java·开发语言·spring boot·redis·后端·java-ee·intellij-idea
篱笆院的狗5 小时前
如何使用 Redis 快速实现布隆过滤器?
数据库·redis·缓存
小鸡脚来咯6 小时前
redis分片集群架构
数据库·redis·架构
什么都想学的阿超6 小时前
【Redis系列 03】掌握Redis编程艺术:事务、管道与Lua脚本完全指南
redis·junit·lua
想用offer打牌10 小时前
面试官问:Redis和MySQL数据一致,为什么还需要MySQL?🤠
数据库·redis·mysql
chen.@-@10 小时前
后端下载限速(redis记录实时并发,bucket4j动态限速)
数据库·redis·缓存
呼拉拉呼拉10 小时前
Redis高可用架构
数据库·redis·架构·高可用架构
用户791177242358311 小时前
黑马点评【基于redis实现共享session登录】
java·redis