redis 锁 set nx 的顺序影响功能实现是什么原因

在实现防止重复提交功能时,采用 redis 锁来实现,写好了一版之后本地测试正常,但是放到线上发现还是有重复的内容
通过在网上搜索之后发现代码的不同之处进行修改,已成功修复问题,但是原理没看懂,测试代码如下,忽略未实现释放的逻辑

// 有问题的代码
$rs = Redis::set($key, $value, 'nx', 'ex', 3);
if (!$rs) {
    return response()->json([], 204);
}

// 有效的代码
$rs = Redis::set($key, $value, 'ex', 3, 'nx');
if (!$rs) {
    return response()->json([], 204);
}

可以看到唯一不同的地方就是nx的位置,问题是我本地测试第一种也是可行的
另线上环境采用负载均衡,部署了多个实例
本地通过使用 redis-cli monitor 监控运行的命令,发现最终运行的语句也只有顺序的不同,然后复制语句在线上的 redis-cli 中运行,也是正确的结果
线上 redis 版本为阿里云的 5.0.5
不知道大家有没有同样的问题,出现问题的原因有没有人能分析一下

风吹枫落
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
讨论数量: 12

可以直接使用\Illuminate\Support\Facades\Cache::driver('reids')->lock($key, $value);

更方便处理缓存系统《Laravel 9 中文文档》

1年前 评论
风吹枫落 (楼主) 1年前

如果你本地测试是用单个浏览器的get请求测试,那是没有并发问题的,加不加分布式锁都不会有并发问题

1年前 评论
风吹枫落 (楼主) 1年前

看 Redis::set 的源码啊

1年前 评论
风吹枫落 (楼主) 1年前

$rs = Redis::set($key, $value, 'ex', 3, 'nx'); 是标准写法,任何情况都不会出错

可以手动在线上redis-cli执行第一种的写法试试,应该是你本地和线上redis版本不一样导致的

1年前 评论
风吹枫落 (楼主) 1年前
Rache1 1年前
风吹枫落 (楼主) 1年前
1年前 评论
风吹枫落 (楼主) 1年前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!