1.慕课高并发实战,卖超问题压测的时候,秒杀商品库存为0,但是在压测过程中,生成的订单数与秒杀订单数远远超过库存数
2.Controller层
@RequestMapping(value = "/do_seckill", method = RequestMethod.POST)
@ResponseBody
public Result<OrderInfo> seckill(Model model, SeckillUser seckillUser,
@RequestParam("goodsId") long goodsId){
model.addAttribute("user", seckillUser);
if(seckillUser == null) {
return Result.error(CodeMsg.SESSION_ERROR);
}
//判断库存
GoodsVO goods = goodsService.getGoodsByGoodsId(goodsId);//10个商品,req1 req2
int stock = goods.getStockCount();
if(stock <= 0) {
return Result.error(CodeMsg.GOODS_EMPTY);
}
//判断是否已经秒杀到了
SeckillOrder order = orderService.getSeckillOrderByUserIdGoodsId(seckillUser.getId(), goodsId);
if(order != null) {
return Result.error(CodeMsg.REPEATE_SECKILL);
}
//减库存 下订单 写入秒杀订单
OrderInfo orderInfo = seckillService.seckill(seckillUser, goods);
return Result.success(orderInfo);
}
2.service层
SeckillService
@Transactional
public OrderInfo seckill(SeckillUser user, GoodsVO goods) {
//减库存 下订单 写入秒杀订单
goodsService.reduceStock(goods);
//order_info sl_order
return orderService.createOrder(user, goods);
}
GoodsService
public void reduceStock(GoodsVO goods) {
SeckillGoods g = new SeckillGoods();
g.setGoodsId(goods.getId());
goodsDao.reduceStock(g);
}
OrderService
/**
* 判断该用户是否秒杀成功,从redis中获取
* @param userId
* @param goodsId
* @return
*/
public SeckillOrder getSeckillOrderByUserIdGoodsId(long userId, long goodsId) {
//return orderDao.getSeckillOrderByUserIdGoodsId(userId, goodsId);
return redisService.get(OrderKey.getSeckillOrderByUidGid,""+userId+"_"+goodsId, SeckillOrder.class);
}
//下订单 order_info sl_order
@Transactional
public OrderInfo createOrder(SeckillUser seckillUser, GoodsVO goodsVO){
OrderInfo orderInfo = new OrderInfo();
orderInfo.setCreateDate(new Date());
orderInfo.setDeliveryAddrId(0L);
orderInfo.setGoodsCount(1);
orderInfo.setGoodsId(goodsVO.getId());
orderInfo.setGoodsName(goodsVO.getGoodsName());
orderInfo.setGoodsPrice(goodsVO.getSeckillPrice());
orderInfo.setOrderChannel(1);
orderInfo.setStatus(0);
orderInfo.setUserId(seckillUser.getId());
long orderId = orderDao.insertOrder(orderInfo);
SeckillOrder miaoshaOrder = new SeckillOrder();
miaoshaOrder.setGoodsId(goodsVO.getId());
miaoshaOrder.setOrderId(orderId);
miaoshaOrder.setUserId(seckillUser.getId());
orderDao.insertSeckillOrder(miaoshaOrder);
redisService.set(OrderKey.getSeckillOrderByUidGid, ""+seckillUser.getId()+"_"+goodsVO.getId(), miaoshaOrder);
return orderInfo;
}
//获取秒杀订单
public OrderInfo getSeckillOrderById(long orderId) {
return orderDao.getSeckillOrderById(orderId);
}
dao层
OrderDao
@Insert("insert into order_info(user_id, goods_id, goods_name, goods_count, goods_price, order_channel, status, create_date)values("
+ "#{userId}, #{goodsId}, #{goodsName}, #{goodsCount}, #{goodsPrice}, #{orderChannel},#{status},#{createDate} )")
@SelectKey(keyColumn = "id", keyProperty = "id", resultType = long.class, before = false, statement = "select last_insert_id()")
public long insertOrder(OrderInfo orderInfo);
@Insert("insert into sl_order(user_id, goods_id, order_id) values (#{userId},#{goodsId},#{orderId})")
public int insertSeckillOrder(SeckillOrder seckillOrder);
GoodsDao
@Update("update sl_goods set stock_count = stock_count - 1 where goods_id = #{goodsId} and stock_count > 0")
public int reduceStock(SeckillGoods seckillGoods);
数据库:
在秒杀商品的秒杀表,简历了用户与商品的联合唯一索引
麻烦大家帮我解决一下