首页 新闻 会员 周边

请教一个抢单并发的问题。

0
悬赏园豆:20 [待解决问题]

请教各位大佬一个.net并发问题,业务是这样的,商家在平台发了抢单任务数量是1个(数量限制),网站上面做任务的用户都可以来抢这个任务,本来任务数量是一个,正常的话只能产生一条订单,结果却产生的了两条订单(两个用户同时抢到了),订单创建的时间分毫不差,请教各位大佬像这种情况该如何解决。

lhyterry的主页 lhyterry | 初学一级 | 园豆:102
提问于:2020-12-24 15:06
< >
分享
所有回答(8)
0

如果是单个服务器,最简单,加个lock就行了
如果涉及到多服务器,分布式,可以考虑用队列处理,把订单产生的消息放到消息队列里面,然后也是一个一个消费,这样就不会出现你说的脏数据超卖的现象

不知道风往哪儿吹 | 园豆:2035 (老鸟四级) | 2020-12-24 15:12

单服务器,加锁这个考虑过,如果单纯的加把锁,不是把整个业务所及都锁住了,因为有其他任务在进行

支持(0) 反对(0) lhyterry | 园豆:102 (初学一级) | 2020-12-24 15:16

@lhyterry: 你只需要在抢的那个地方加锁就行了,又不是整个过程都加锁

支持(0) 反对(0) 不知道风往哪儿吹 | 园豆:2035 (老鸟四级) | 2020-12-24 15:18

@不知道风往哪儿吹: 已经尝试加锁测试了,还是有同样的问题!

支持(0) 反对(0) lhyterry | 园豆:102 (初学一级) | 2020-12-24 15:51

@lhyterry: 订单创建的时间也是一样的? 用户不一样?

支持(0) 反对(0) 不知道风往哪儿吹 | 园豆:2035 (老鸟四级) | 2020-12-24 15:59
0

根据情况复杂程度来考虑:

1.并发不高,简单的话,加锁,加确认,lock;
2.通过数据库唯一键,来处理,插入指定的数据,唯一约束处理;
3.消息队列来处理,rabbitmq 等;

HSCOrange | 园豆:206 (菜鸟二级) | 2020-12-24 15:30

已经尝试加锁测试了,还是有同样的问题!

支持(0) 反对(0) lhyterry | 园豆:102 (初学一级) | 2020-12-24 15:50

@lhyterry: 那就换其他方式

支持(0) 反对(0) HSCOrange | 园豆:206 (菜鸟二级) | 2020-12-24 16:10
0

这么简单的东西加队列消费..........商品的数量就是一开始固定队列长,完成订单后队列-1数据库更新,没必要加锁........

小小咸鱼YwY | 园豆:3210 (老鸟四级) | 2020-12-24 16:59
0

按你之前逻辑处理,最终 减库存时,同时更新订单状态为有效 ,update 自带锁
mssql 参考
update 库存表 set 数量=数量-1 where id= xxx and 数量>0
if @@ROWCOUNT=1 -- 前一句update执行 set 更新了成功
update 订单 set 状态=有效 where id=订单号

pencile | 园豆:845 (小虾三级) | 2020-12-24 17:11
0

本来就是靠运气的事,给每个订单加个Guid,第一个字符谁小订单给谁

Jaguar_Jacky | 园豆:458 (菜鸟二级) | 2020-12-24 17:48
0

可以使用 redis 分布式锁

dudu | 园豆:30994 (高人七级) | 2020-12-24 19:43
0

var asynclock = new semaphoreslim(1)
多个线程:
await asynclock.waitasync()
createorder()
asynclock.release()

// 2
static readonly object obj = new object();
lock(obj) {
createorder()
}
// 不想阻塞可以使用 monitor.tryenter

沉睡的木木夕 | 园豆:19 (初学一级) | 2020-12-24 21:15
0

不可以在数据库里把这个任务的ID当成唯一键吗,反正数据库不可以重复插入

yytxdy | 园豆:1680 (小虾三级) | 2020-12-25 17:36
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册