欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

秒杀抢购(异步处理,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);
    }