畅购商城(一):环境搭建
畅购商城(二):分布式文件系统FastDFS
畅购商城(三):商品管理
畅购商城(四):Lua、OpenResty、Canal实现广告缓存与同步
畅购商城(五):Elasticsearch实现商品搜索
畅购商城(六):商品搜索
畅购商城(七):Thymeleaf实现静态页
畅购商城(八):微服务网关和JWT令牌
畅购商城(九):Spring Security Oauth2
畅购商城(十):购物车
畅购商城(十一):订单
畅购商城(十二):接入微信支付
畅购商城(十三):秒杀系统「上」
畅购商城(十四):秒杀系统「下」
防止秒杀重复排队回顾一下上一篇文章中讲到的下单的流程。当用户点击下单之后,用户名和商品id就会组装成一个SeckillStatus对象存入Redis队列中等待被处理,这个过程叫做排队。所以说,只要用户点击了一次下单后不论最后是否下单成功,他都会进入到排队的状态。如果用户重复点击下单,那么Redis队列中就会有很多个相同的SeckillStatus对象,也就是一个用户排队多次,这显然是不符合逻辑的,一个用户应该只能排队一次。
为了避免用户重复排队的情况,可以为每个用户在Redis中设置一个自增值,每次排队的时候加1,如果大于1,说明重复排队了,那么直接抛出异常,告诉用户重复排队了。
//SeckillOrderServiceImpl @Override public boolean add(Long id, String time, String username) { Long increment = redisTemplate.boundHashOps(SystemConstants.SEC_KILL_USER_QUEUE_COUNT).increment(username, 1); if (increment>1) { //记录指定hashkey的增量,大于1说明排队次数超过1次,重复排队 throw new RuntimeException("重复排队"); } ………… }这段代码中,添加了对用户重复排队的判断,先自增1,再进行判断。这里的key设置的是username,因为一个用户只能下单一件商品,如果去下单其它商品,同样也是重复排队。
测试了一下,是成功的。但是有一个问题:如果用户在这里排队未成功,该怎么清理排队信息呢?这个下一步就会说,接着往下看