请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

正在回答 回答被采纳积分+3

2回答

若鱼1919 2018-03-19 08:46:39

int stock = redis.decr();

if(stock <= 0){  

  return 库存不足;

}

假如现在的库存数是1,两个线程同时做decr,库存数就变成-1了。同理,如果有100个并发,那库存数就是-99.

1 回复 有任何疑惑可以回复我~
  • 提问者 luotuo1089 #1
    好的,明白了,谢谢老师!
    回复 有任何疑惑可以回复我~ 2018-03-26 10:18:31
慕无忌9148628 2018-07-17 04:40:30

但是这种情况会有可能出现少卖的情况 压测的时候发现的

我认为MiaoshaController中应该把redis的decr方法和if放到一起才是线程安全的

if(redisService.decr(GoodsKey.getMiaoshaGoodsStock, ""+goodsId) < 0) {

    return Result.error(CodeMsg.MIAO_SHA_OVER);

}

还要麻烦老师来评价一下我认为的是否正确,谢谢


0 回复 有任何疑惑可以回复我~
  • (1)不正确 两句代码放到一行跟放到两行没有任何区别
    (2)这里不会导致少卖,有2种情况会导致少卖,一是同一个用户发出了多个请求,这些请求同时到达了服务器,如果此时有足够的库存就可能会产生少卖;二是如果redis预减库存成功,后面的处理出现了异常也会导致少卖。
    回复 有任何疑惑可以回复我~ 2018-07-17 08:22:32
  • 不好意思 最近异步搞的太多 脑子进水了 栈变量都是线程封闭安全的 应该是我后面的处理异常了 谢谢答复
    回复 有任何疑惑可以回复我~ 2018-07-18 17:58:59
  • 老师,我记得redis的decr是原子操作,这里变为负数,是因为后续判断没有做完,然后其他线程继续进去执行incr造成的吗?可以给我说一下为啥说incr是原子的,却能造成负数情况吗?是我理解的这样不?
            //使用redis进行预减少库存
            Long stock = redisService.decr(GoodsKey.GOODS_STOCK_ID, "" + goodsId);//10
            //如果小于0,库存完结,直接返回
            if (stock < 0) {
                localOverMap.put(goodsId, true);
                return Result.error(CodeMsg.MIAO_SHA_OVER);
            }
    回复 有任何疑惑可以回复我~ 2020-05-05 11:33:41
问题已解决,确定采纳
还有疑问,暂不采纳
意见反馈 帮助中心 APP下载
官方微信