什么是超卖
库存只有1个,当有两个线程过来后,都执行成功了,生成了两个订单,这就是超卖
避免超卖的发生
下面的代码还是会发生超卖。虽然减库存,生成订单在同一个事务,也对修改库存做了限制,但是即使stock_count变为0了,这个减库存的sql操作也不会报错,导致后面的生成订单就会正常执行
导致库存和订单数量不一致
@Transactional public OrderInfo miaosha1(MiaoshaUser user, GoodsVo goods) { //减库存 下订单 写入秒杀订单 // 减库存 sql // @Update("update miaosha_goods set stock_count = stock_count - 1 where stock_count > 0 and goods_id = #{goodsId}") goodsService.reduceStock(goods); return orderService.createOrder(user, goods); }
修改之后的
@Transactional public OrderInfo miaosha(MiaoshaUser user, GoodsVo goods) { //减库存 //update miaosha_goods set stock_count = stock_count - 1 where stock_count > 0 and goods_id = #{goodsId} boolean res = goodsService.reduceStock(goods); if(res){//执行减库存成功后,才创建订单 //order_info maiosha_order return orderService.createOrder(user, goods); } throw new GlobalException(CodeMsg.MIAO_SHA_OVER); }
总结:避免发生超卖:
1)更新库存时候,库存数量作限制stock_count>0
2) 减库存成功后再创建订单
3)减库存,生成订单在同一事务里