秒杀项目中,超卖问题解决了,但是出现生成的订单数远大于卖出商品的数目!!!

1、问题描述
@Transactional
public OrderInfo miaosha(MiaoshaUser user, GoodsVo goods) {
   //减库存 下订单 写入秒杀订单
   goodsService.reduceStock(goods);
   //order_info maiosha_order
   return 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_order
   return 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查看日志锁定住了问题,这样解决起问题来方向感就会比较强。

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值