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
不知道大家有没有同样的问题,出现问题的原因有没有人能分析一下

风吹枫落
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
讨论数量: 12

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

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

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

看 Redis::set 的源码啊

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

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

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

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

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

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

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