远大于卖出商品的数目!!!"/>
秒杀项目中,超卖问题解决了,但是出现生成的订单数远大于卖出商品的数目!!!
1、问题描述
@Transactional
public OrderInfo miaosha(MiaoshaUser user, GoodsVo goods) {//减库存 下订单 写入秒杀订单goodsService.reduceStock(goods);//order_info maiosha_orderreturn orderService.createOrder(user, goods);
}//减库存
public void reduceStock(GoodsVo goods) {MiaoshaGoods g = new MiaoshaGoods();g.setGoodsId(goods.getId());goodsDao.reduceStock(g);
}
//减库存
@Update("update miaosha_goods set stock_count = stock_count - 1 where goods_id = #{goodsId} and stock_count > 0")
public int reduceStock(MiaoshaGoods g);
按照项目的思路
1.减库存的SQL语句加上了stock_count > 0,这样就解决了库存减到负数的情况。
2.miaosha_order这个表增加唯一索引(user_id, goods_id),这样就能使一个用户对应一个商品只能生成一个订单。这样就不可能出现一个用户发出两次请求,将这个商品秒杀了两次,导致一个用户对应一个商品却生成了两个订单。
但是,虽然看上去很好理解感觉也很对,实际压测确实满足了上述1、2两个条件,但是出现了新的问题。就是生成的订单数量远大于卖出商品的数量。
秒杀前:针对id=1的商品,库存使10。这里我只用了300个线程并发。
秒杀后:生成了14个订单,大于商品数量10,显然这种情况是不合理的。
2、问题解决
@Transactional
public OrderInfo miaosha(MiaoshaUser user, GoodsVo goods) {//减库存 下订单 写入秒杀订单if(goodsService.reduceStock(goods)==0){return null;//如果这条减库存的SQL执行失败返回0,那么就直接返回,不要再执行下面的下订单了。} //order_info maiosha_orderreturn orderService.createOrder(user, goods);
}public int reduceStock(GoodsVo goods) {MiaoshaGoods g = new MiaoshaGoods();g.setGoodsId(goods.getId());//flag标记这条SQL是否执行成功。0不成功,1成功。int flag=goodsDao.reduceStock(g);return flag;
}
代码这样写后就能在满足上述1、2两个效果的基础上,也满足生成的订单数和卖出的商品数量一致。
3、总结
1.问题原因:用户执行减库存的操作失败了,但是依然会去执行下订单的操作,这样就形成了生成的订单数大于卖出的商品数。
2.刚开始在乐观锁和悲观锁方面去找思路解决这个问题,还是没解决,但是对乐观锁的理解加深了。
3.学习的过程中,总是会遇到各种问题,只有自己动手写了出现bug了,再去疯狂debug解决问题,这个过程营养是真的丰富!!!出现问题心态要稳,debug的能力非常重要,初级阶段写的代码真的就是一坨屎,各种bug,只有debug查看日志锁定住了问题,这样解决起问题来方向感就会比较强。
更多推荐
秒杀项目中,超卖问题解决了,但是出现生成的订单数远大于卖出商品的数目!!!
发布评论