什么是超賣
庫存只有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)減庫存,生成訂單在同一事務里
