悲观锁+获取动态代理解决一人一单效果

// 保证了只要id值一样就会上锁 而不是根据对象
UserDTO user = UserHolder.getUser();
Long userId = user.getId();
synchronized (userId.toString().intern()) {
    // 要实现事务需要通过代理对象
    IVoucherOrderService proxy = (IVoucherOrderService) AopContext.currentProxy();
    return proxy.getResult(voucherId);
}

@Transactional
    public Result getResult(Long voucherId) {
        // 一人一单
        UserDTO user = UserHolder.getUser();
        Long userId = user.getId();
        // 锁加在这个位置不能确保事务提交了
//        synchronized (userId.toString().intern()) {
            Integer count = seckillVoucherService.query().eq("user_id", userId).eq("voucher_id", voucherId).count();
            if (count >= 1) {
                return Result.ok("用户已经购买过了!");
            }
            // 是的话 更新数据库 创建订单 返回订单id
            boolean flag = seckillVoucherService.update().setSql("stock = stock-1").
                    eq("voucher_id", voucherId).gt("stock", 0)
                    .update();
            if (!flag) {
                return Result.fail("活动已经结束!");
            }
            // 生成订单
            // 订单id 用户id 代金卷的id
            VoucherOrder voucherOrder = new VoucherOrder();
            // 代金卷id
            voucherOrder.setVoucherId(voucherId);
            // 订单id
            long orderId = redisWorker.generateId("order");
            voucherOrder.setId(orderId);
            // 用户id

            voucherOrder.setUserId(userId);
            // 保存
            save(voucherOrder);
            return Result.ok(orderId);
//        }
    }

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值