会出现多抢库存为-1的情况

来源:6-3 如何实现商品秒杀?(三)

Peter陳

2019-07-16

KillTask的代码

    int num = Integer.parseInt(jedis.get("kill_num"));
    if (num > 0) {
        jedis.watch("kill_num", "kill_user");
        Transaction transaction = jedis.multi();
        transaction.decr("kill_num");
        transaction.rpush("kill_user", "9527");
        transaction.exec();
    } else {
        Application.pool.shutdown();
    }

在库存为1的时候。如果两个线程同时去取jedis.get(“kill_num”),都拿到num=1.然后,都进入了redis事务的代码。最后就会出现库存为-1或-2的现象。我本地的测试也出现了这种情况。请老师提供解决方案。
jedis.watch之前取num的代码,老师没有做到事务的一致性。

写回答

3回答

FrankLi_

2019-12-22

改成先watch再get做判断就不会了。现在的代码的确可能会超卖,发生在线程1get之后判断了还没有watch,其他线程扣减完成了的情况。我建议用lua脚本,性能会更高。

0
0

大喵爱学习

2019-11-16

哈哈,同学,太感谢你啦!找到问题啦

0
0

神思者

2019-07-16

我在Linux上运行redis的结果是正常的,你是在Linux上运行的redis吗?

0
5
96年的nash
回复
Peter陳
感谢指导,学习了
2019-11-15
共5条回复

阿里新零售数据库设计与实战 (升级版)

解锁“新零售”业务让数据库实战能力再上一层楼

2101 学习 · 701 问题

查看课程