Redis-黑马点评项目-07-jmeter测试-200个线程抢购100个秒杀券超卖问题

1.问题描述

由于高并发,会出现超卖问题,解决办法就是
悲观锁与乐观锁,乐观锁有版本号和CAS两种解决办法,采用CAS解决

2.代码

主要在这个地方,在更新减库存的时候,要直接判断是不是库存是否大于0。
在这里插入图片描述

@Service
public  class VoucherOrderServiceImpl extends ServiceImpl<VoucherOrderMapper, VoucherOrder> implements IVoucherOrderService {

    @Resource
    ISeckillVoucherService seckillVoucherService;

    @Resource
    private RedisIdWorker redisIdWorker; //订单id生成器 全局唯一id

    @Transactional()
    @Override
    public Result seckillVoucher(Long voucherId) {
        // 1.查询优惠劵

        SeckillVoucher voucher = seckillVoucherService.getById(voucherId);
        // 如果查不到结果(即没有匹配的记录),这个方法会直接返回 null。
        if (voucher == null) {
            return  Result.fail("优惠券不存在");
        }

        // 2.判断秒杀是否开始
        if(voucher.getBeginTime().isAfter(LocalDateTime.now()))
        {
            return Result.fail("秒杀还没有开始");
        }
        // 3. 判断秒杀是否已经结束
        if(voucher.getEndTime().isBefore(LocalDateTime.now()))
        {
            return Result.fail("秒杀已经结束");
        }
        // 4.判断库存是否存在
        if(voucher.getStock()<1)
        {
            return  Result.fail("库存不足");
        }

        // 5.扣减库存
        /*
        UPDATE seckill_voucher
        SET stock = stock - 1
        WHERE voucher_id = #{voucherId}
        */
        boolean success = seckillVoucherService.update()
                .setSql("stock = stock-1")
                .eq("voucher_id", voucherId)
                .gt("stock", 0)
                .update() ;
        // 秒杀  悲观锁和乐观锁(版本号法(不会出现ABA问题)和CAS法(可能出现ABA问题)),秒杀不会发生ABA问题,因为库存只会减,不会增
        if(!success)
        {
            return Result.fail("库存不足");
        }

        // 6.创建订单  订单表
        VoucherOrder voucherOrder = new VoucherOrder();

        // 6.1 订单id
        long voucherOrderId = redisIdWorker.nextId("voucherOrder");//传入的是前缀
        voucherOrder.setId(voucherOrderId);

        // 6.2 用户id  拦截器获取
        UserDTO user = UserHolder.getUser();
        if(user==null)
        {
            return  Result.fail("用户没有登陆,无法抢购优惠劵");
        }  // 也可以在拦截器中实现
        voucherOrder.setUserId(user.getId());

        // 6.3 代金券id
        voucherOrder.setVoucherId(voucherId);

        save(voucherOrder);


        // 7.返回订单id
        return Result.ok(voucherOrderId);
    }
}

3.jmeter测试bug

在这里插入图片描述

很奇怪,为什么不是50%,数据库100个卷都已经卖出去了。
原来是要清理,点击清理按钮即可,再加上响应断言
在这里插入图片描述

4.最终效果图

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值