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

相关推荐
嘻哈baby8 小时前
Redis高可用部署与集群管理实战
数据库·redis·bootstrap
Java爱好狂.11 小时前
Java面试Redis核心知识点整理!
java·数据库·redis·分布式锁·java面试·后端开发·java八股文
阿杆11 小时前
如何在 Spring Boot 中接入 Amazon ElastiCache
java·数据库·redis
此生只爱蛋16 小时前
【Redis】String 字符串
java·数据库·redis
青云交16 小时前
Java 大视界 -- 基于 Java+Flink 构建实时电商交易风控系统实战(436)
java·redis·flink·规则引擎·drools·实时风控·电商交易
破烂pan17 小时前
Python 整合 Redis 哨兵(Sentinel)与集群(Cluster)实战指南
redis·python·sentinel
SoleMotive.17 小时前
redis和mysql有什么区别,以及redis和mysql都有什么缺点,以及什么地方redis不如mysql?
数据库·redis·mysql
锥锋骚年18 小时前
golang 开发 Redis与Memory统一接口方案
开发语言·redis·golang
bafuka18 小时前
别再手撸热点缓存了:一个注解搞定Redis热点问题(已开源)
redis
程可爱18 小时前
详解Redis的五种基本数据类型(String、List、Hash、Set、ZSet)
redis