@RequestMapping(value = "/do_miaosha") @ResponseBody public String Miaosha(MiaoshaUser user, Model model, @RequestParam("goodsId")long goodsId){ /*判断是否登陆*/ if (user == null){ return "login"; } GoodsVo goodsVo = goodsService.getGoodsById(goodsId); int stock = goodsVo.getStockCount(); if (stock <= 0){ // 小于等于0 不能是==0 单线程没有问题 model.addAttribute("errMsg",CodeMsg.MIAO_SHA_NO_STOCK.getMsg()); return "miaosha_fail";/*返回到秒杀失败页面*/ } /*判断是否重复秒杀*/ MiaoshaOrder miaoshaOrder = orderService.getMiaoshaByUserAndGood(user.getId(),goodsId); if (miaoshaOrder != null){ model.addAttribute("errMsg",CodeMsg.MIAO_SHA_REPEAT.getMsg()); return "miaosha_fail"; } /*都过了.执行秒杀*/ /**执行秒杀: 事务 用 秒杀service 完成 * * */ OrderInfo orderInfo = miaoshaService.miaosha(user,goodsVo); model.addAttribute("orderInfo",orderInfo);/* 将订单 信息写入 域中*/ model.addAttribute("goods",goodsVo);/*商品信息 也写入*/ return "order_detail"; }
主要逻辑:1.判断登录 2.根据post提交的商品id 从数据库拿到商品,3.判断库存,库存足够 下一步 4.判断是否重复秒杀,即从数据库根据商品和用户id 查询秒杀订单表,如果已经存在订单,说明重复秒杀
最终才能让该用户秒杀商品:
秒杀业务逻辑:1.减库存,2.加订单
@Transactional public OrderInfo miaosha(MiaoshaUser user, GoodsVo goodsVo) { /*减库存*/ //该方法返回一个int型数值 boolean succes = goodsService.reduceStock(goodsVo); if (succes){//减库存成功 /*下订单*/ return orderService.insertOrder(user,goodsVo); }else {//失败 说明 商品已经被秒杀完了 //秒杀完了,就做一个标记 通过这个标记来判断是不是因为卖完了,而没有记录 setGoodsOver(goodsVo.getId()); return null; } }
@Service public class GoodsService { @Autowired private GoodsDao goodsDao; public List<GoodsVo> getGoodsList(){ return goodsDao.getGoodsList(); } public GoodsVo getGoodsById(Long goodsId){ return goodsDao.getGoodsById(goodsId); } //减库存 public boolean reduceStock(GoodsVo goodsVo) { MiaoshaGoods goods = new MiaoshaGoods(); goods.setGoodsId(goodsVo.getId()); int ret = goodsDao.reduceStock(goods);//返回 的是 执行的条数 return ret > 0; } }
/**下订单方法: 返回一个订单对象 并且 要向2个order表中都加入信息 * orderinfo 以及 miaosha_order * @param user * @param goodsVo * @return */ @Transactional public OrderInfo insertOrder(MiaoshaUser user, GoodsVo goodsVo) { OrderInfo orderInfo = new OrderInfo(); /*设置订单信息*/ orderInfo.setGoodsId(goodsVo.getId()); orderInfo.setCreateDate(new Date()); orderInfo.setUserId(user.getId()); orderInfo.setDeliveryAddrId(1L); orderInfo.setGoodsCount(1); orderInfo.setGoodsName(goodsVo.getGoodsName()); orderInfo.setOrderChannel(1); orderInfo.setGoodsPrice(goodsVo.getGoodsPrice()); orderInfo.setStatus(0); /*插入 订单信息 order_info*/ orderDao.insertOrder(orderInfo); /*插入秒杀订单信息*/ MiaoshaOrder miaoshaOrder = new MiaoshaOrder(); miaoshaOrder.setGoodsId(goodsVo.getId()); miaoshaOrder.setOrderId(orderInfo.getId()); miaoshaOrder.setUserId(user.getId()); orderDao.insertMiaoshaOrder(miaoshaOrder); /**创建订单之后将订单加入缓存 * */ redisService.set(OrderKey.getOrderByUidGid,user.getId()+"-"+goodsVo.getId(),miaoshaOrder); return orderInfo; }
事务 ----同时减库存和下订单,其中一一步错了,回滚,定义@Transactional