使用单机版锁 解决订单超卖场景(一)

目标:

巧用锁 解决订单超卖场景


步骤:

1、启动Redis环境
2、 搭建一个demo(单机版),消费同一个redis的key
3、加锁!
4、使用Apifox并发消费,看结果

Tips:其余步骤可看上篇博客

二:搭建一个demo(单机版),消费同一个redis的key

三:加锁!

加上单机版的锁:ReentraLock

@RestController
public class GoodsController {
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Value("${server.port}")
    private String serverPort;

    private final ReentrantLock COMMON_LOCK = new ReentrantLock();

    @GetMapping("/bug_1")
    public String bugGoods_1(){
        COMMON_LOCK.lock(); // 执行业务代码前加锁
        try{
            // 查看redis中库存数量
            String res = stringRedisTemplate.opsForValue().get("goods:001");
            int goodsNum = res == null ? 0 : Integer.parseInt(res);
            if(goodsNum > 0 ){
                int realNum = goodsNum - 1;
                stringRedisTemplate.opsForValue().set("goods:001",String.valueOf(realNum));
                System.out.println("bugGoods_1:成功购买商品,库存仅剩:"+realNum);
                return "bugGoods_1:成功购买商品,库存仅剩:"+realNum;
            }else{
                System.out.println("bugGoods_1:商品售罄");
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally{
            COMMON_LOCK.unlock(); // finally 最终释放锁
        }
        return "bugGoods_1:商品售罄";
    }
    @GetMapping("/bug_2")
    public String bugGoods_2(){
        COMMON_LOCK.lock();
        try {
            // 查看redis中库存数量
            String res = stringRedisTemplate.opsForValue().get("goods:001");
            int goodsNum = res == null ? 0 : Integer.parseInt(res);
            if(goodsNum > 0 ){
                int realNum = goodsNum - 1;
                stringRedisTemplate.opsForValue().set("goods:001",String.valueOf(realNum));
                System.out.println("bugGoods_2:成功购买商品,库存仅剩:"+realNum);
                return "bugGoods_2:成功购买商品,库存仅剩:"+realNum;
            }else{
                System.out.println("bugGoods_2:商品售罄");
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally{
            COMMON_LOCK.unlock();
        }
        return "bugGoods_2:商品售罄";
    }
}

或者单机版的锁:synchronized

@GetMapping("/buy01")
    public String buy_01(){
        synchronized (this){
            try {
                // 查看redis中库存数量
                String res = stringRedisTemplate.opsForValue().get("goods:001");
                int goodsNum = res == null ? 0 : Integer.parseInt(res);
                if(goodsNum > 0 ){
                    int realNum = goodsNum - 1;
                    stringRedisTemplate.opsForValue().set("goods:001",String.valueOf(realNum));
                    System.out.println("buy01:成功购买商品,库存仅剩:"+realNum);
                    return "buy01:成功购买商品,库存仅剩:"+realNum;
                }else{
                    System.out.println("buy01:商品售罄");
                }
            }catch (Exception e){
                e.printStackTrace();
            }
            return "buy01:商品售罄";
        }
    }
    @GetMapping("/buy02")
    public String buy_02(){
        synchronized (this){
            try {
                // 查看redis中库存数量
                String res = stringRedisTemplate.opsForValue().get("goods:001");
                int goodsNum = res == null ? 0 : Integer.parseInt(res);
                if(goodsNum > 0 ){
                    int realNum = goodsNum - 1;
                    stringRedisTemplate.opsForValue().set("goods:001",String.valueOf(realNum));
                    System.out.println("buy02:成功购买商品,库存仅剩:"+realNum);
                    return "buy02:成功购买商品,库存仅剩:"+realNum;
                }else{
                    System.out.println("buy02:商品售罄");
                }
            }catch (Exception e){
                e.printStackTrace();
            }
            return "buy02:商品售罄";
        }
    }

四:使用Apifox并发消费,看结果

在这里插入图片描述
Reentralock实现结果:
在这里插入图片描述
synchronized实现结果:
在这里插入图片描述

至此,单机版的加锁即可解决超卖现象

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值