
提交订单功能,判断当前用户有没有提交订单(订单创建成功会保存到 redis )。以下是伪代码,逻辑和提交订单是一样的,遇到的问题也是一样的,请求老牛解决!
ConcurrencyTester tester= ThreadUtil.concurrencyTest(1000, () -> { Set<String> keys = redisTemplate.keys("key");//查询 redis 有没有这个 key,有就返回 key if (keys.size() > 0) { return; } System.out.println("我来插入到 redis"); //此处被执行多次 redisTemplate.opsForValue().set("key", "value"); });
1 Jooooooooo 2021-06-06 00:39:00 +08:00 搜一下 setnx 当然用 redis 做锁当发生故障时极小概率保障不了唯一性, 看你的需求了 |
2 swulling 2021-06-06 00:52:41 +08:00 一年开发经验,特别是做高并发,首先需要了解一个概念叫做并发冲突。 查询 Key 是否存在 + 设定 Key 的 Value,这两步在你的实现里不是原子的。解决办法就是使用原子操作替代两步操作。 |
3 ccde8259 2021-06-06 01:01:13 +08:00 via iPhone 为什么不用 SETNX 为什么不用 MULTI WATCH 为什么不用 LUA SCRIPT |
4 Hurriance 2021-06-06 01:11:12 +08:00 不嫌麻烦的话可以用 lua + 2 楼的方法 |
5 jones2000 2021-06-06 03:12:44 +08:00 直接插入不覆盖的模式, 如果插入成功就说明是新订单, 插入失败就说明订单已存在。 |
6 Addup 2021-06-06 03:16:36 +08:00 用 lua 注意定时清理下脚本缓存, 这里有两个坑: 不然不断累积导致内存爆满, 建有 dts 的话从机也需要执行命令清脚本缓存, 脚本缓存过多时, 清除命令耗时过长可能导致 dts 连接异常. |
7 fewok &nbp; 2021-06-06 04:17:45 +08:00 咱们先说人话,你们交易业务,下单最高峰,秒杀最高峰的 TPS 是多少??? |
8 jorneyr 2021-06-06 08:27:00 +08:00 redisTemplate.keys("key"); Java 代码在这里并发了,多个线程执行到这里时 key 不存在,则进行了多条插入。 Redis 的单线程保证的是自己内部,Java 端的并发 Redis 处理不了。 |
9 limuyan44 2021-06-06 09:21:31 +08:00 对于并发而言,这种问题过于常识了,建议先找点相关的文章看看,这还是涉及钱的下单功能,这么搞迟早把自己坑死。 |
10 szzadkk 2021-06-06 10:00:17 +08:00 这个操作不是原子性的,肯定有问题,用 setnx 或者 lua 脚本 |
11 ttyn 2021-06-06 11:00:49 +08:00 猜测你本意是用 Redis 做并发锁,防止订单重复提交。 要理解你失败的原因,需要先了解 Redis 的原子操作,作为一年的开发经验,有点为难你。 Redis 有个现成的东西,叫 Redlock,参考: https://blog.csdn.net/hanchao5272/article/details/99695360 |
14 Jekins OP 感谢楼上各位老哥! |
16 pydiff 2021-06-07 10:52:38 +08:00 有点好奇,究竟是什么样的公司,敢让一个新手来做这种关键业务,如果 boom 了算谁的呢 |
17 shimianxiang 2021-06-07 13:44:21 +08:00 建议直接 lua,还好扩展 |
18 vgbhfive 2021-06-07 14:44:45 +08:00 via Android lua 脚本或者 setnx 保证原子性 |
19 wunsch0106 2021-06-08 11:45:16 +08:00 @pydiff 敢叫他上就敢写呗,boom 了肯定领导负责啊 |
20 neptuno 2021-06-11 14:54:52 +08:00 原子操作,lua+redis 分布式锁,网上随便找个例子模仿写 |
21 OV0 2021-06-16 18:06:59 +08:00 分布式锁的套路:本地锁+分布式锁 + 数据库业务。 |
22 DreamSpace 2021-06-26 00:15:28 +08:00 via Android 楼上说得很明白了,这里在补充一点,如果用 redis.keys(key)做模糊匹配,效率极低,而且会阻塞其他请求!! |
23 siweipancc 2021-06-28 18:52:31 +08:00 via iPhone keys? 真让人头大 |