秒杀抢购(异步处理,webCocket通知用户)
程序员文章站
2022-03-30 20:17:59
...
1.通过商品id和用户id进行抢购
2.符合条件的发送给mq异步处理
3.排队成功,通知用户
4.webCocket通知用户
@Override
public ResponseResult buyCoupon(Long id, Long uid) {
ResponseResult result = ResponseResult.SUCCESS();
try {
TbCoupon tbCoupon = (TbCoupon) redisTemplate.opsForHash().get("couponList", String.valueOf(id));
//获得当前秒杀的商品
long nowTime = new Date().getTime();
long endTime = tbCoupon.getEtime().getTime();
if (nowTime>endTime) {
result.setSuccess(false);
result.setMessage("秒杀活动已结束");
return result;
}
//用户是否已经抢购到(防止重复抢购)
Long add = redisTemplate.opsForSet().add("coupon:" + id, uid);
if (add == 0) {
result.setSuccess(false);
result.setMessage("您已经抢购过该商品,请勿重复操作");
return result;
}
//预减库存
Long decrement = stringRedisTemplate.opsForValue().decrement("coupon:" + tbCoupon.getId());
if (decrement<0) {
result.setSuccess(false);
result.setMessage("没有足够的库存");
return result;
}
HashMap map = new HashMap();
map.put("id",id);
map.put("uid",uid);
//符合条件的发送给mq异步处理
rabbitTemplate.convertAndSend(MqOrder.DirectExchange, MqOrder.DirectOrder,map);
} catch (Exception e) {
result.setSuccess(false);
result.setMessage("正在排队中");
}
return result;
}
@Component
@RabbitListener(queues = {MqOrder.DirectQueue})
@RabbitHandler
public void saveOrder(Map map, Message message, Channel channel) {
ResponseResult result = ResponseResult.FAIL();
Long id = (Long) map.get("id");
Long uid = (Long) map.get("uid");
try {
TbCoupon coupon = tbCouponService.getById(id);
if (coupon.getNum()>0) {
//生成订单
TbOrder order = new TbOrder();
order.setCode(String.valueOf(yxmApplication.getIdWorker().nextId()));
order.setYid(id);
order.setUid(uid);
order.setCtime(new Date());
order.setStatus(0);
tbOrderService.saveOrUpdate(order);
//生成用户优惠券表
TbUcoupon tbUcoupon = new TbUcoupon();
tbUcoupon.setUid(uid);
tbUcoupon.setYid(id);
tbUcouponService.saveOrUpdate(tbUcoupon);
//商品库存减少
coupon.setNum(coupon.getNum()-1);
tbCouponService.updateById(coupon);
//更新缓冲当中的商品库存
redisTemplate.opsForHash().put("couponList",String.valueOf(id),coupon);
//通知用户
result.setSuccess(true);
result.setMessage("恭喜您,抢购成功!!!");
}else {
result.setSuccess(false);
result.setMessage("抢购失败,库存不足");
}
channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
} catch (IOException e) {
result.setSuccess(false);
result.setMessage("下单异常,请稍后再试");
}
String res = JSON.toJSONString(result);
msgWsService.sendMsg(String.valueOf(uid), res);
}
@Configuration
public static final String DirectQueue = "queue_order";
public static final String DirectExchange = "ex_seckill";
public static final String DirectOrder = "rk_order";
@Bean
public Queue directQueue(){
//队列名字,是否持久化
return new Queue(DirectQueue);
}
@Bean
public DirectExchange directExchange() {
//交换器名称、是否持久化、是否自动删除
return new DirectExchange(DirectExchange);
}
@Bean
public Binding binding(Queue directQueue,DirectExchange directExchange) {
return BindingBuilder.bind(directQueue).to(directExchange).with(DirectOrder);
}
上一篇: 清朝最后三位皇帝为什么会绝后 他们没有孩子的原因是什么
下一篇: 主键生成策略