【黑马点评-3秒杀优惠券】一、单体秒杀初始逻辑(不考虑加锁)
涉及的表
tb_voucher:优惠券的基本信息,优惠金额、使用规则等
tb_seckill_voucher:优惠券的库存、开始抢购时间,结束抢购时间。特价优惠券才需要填写这些信息
- voucher_id 主键 关联的优惠券...
- stock 库存
- create time 创建时间
- begin time 生效时间
- end time 失效时间
- update time 更新时间
tb_voucher_order
代码逻辑
1. 查询优惠券信息,并通过数据库里的seckillvoucher的表的字段判断时间等
- SeckillVoucher 这个实体对应tb_seckill_voucher 表,通过实现了IService接口的类自动拥有了getById()方法,返回一个实体类。
- 使用MyBatis自动生成的 getter 方法,进行三个字段的比对
// 1. 查询优惠券信息
SeckillVoucher voucher = seckillVoucherService.getById(voucherId);
// 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("库存不够了");
}
2. 通过链式更新
- 使用MyBatis-Plus的update方法,更新符合条件的记录
- 内置参数为一个实体对象封装操作类Wrapper
- 调用eq语句,找到符合的那个字段的记录
- 使用条件构造器的setSql方法,更新
boolean flag = seckillVoucherService.update(new LambdaUpdateWrapper<SeckillVoucher>().eq(SeckillVoucher::getVoucherId, voucherId).setSql("stock=stock-1"));
3. 创建对应的Voucher实体,保存到数据库中。
- 创建优惠券订单实体
- 然后生成一个uuid的优惠券id作为主键
- 设置userId
- 设置购买的voucherId
// 6. 秒杀成功,创建对应的订单,保存到数据库中
VoucherOrder voucherOrder = new VoucherOrder();
long orderId = redisIdWorker.nextId("seckill_voucher_order");
voucherOrder.setId(orderId);
voucherOrder.setUserId(UserHolder.getUser().getId());
voucherOrder.setVoucherId(voucherId);
flag = this.save(voucherOrder);
示例代码
/**
* 1. 实现优惠券秒杀的下单功能(不考虑冲突)
*/
public Result seckillVoucher1(Long voucherId) {
// 1. 查询优惠券信息
SeckillVoucher voucher = seckillVoucherService.getById(voucherId);
// 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. 秒杀券合法,则秒杀券抢购成功,库存数量-1
boolean flag = seckillVoucherService.update(new LambdaUpdateWrapper<SeckillVoucher>()
.eq(SeckillVoucher::getVoucherId, voucherId).setSql("stock=stock-1"));
if (!flag) {
throw new RuntimeException("秒杀券扣减失败");
}
// 6. 秒杀成功,创建对应的订单,保存到数据库中
VoucherOrder voucherOrder = new VoucherOrder();
long orderId = redisIdWorker.nextId("seckill_voucher_order");
voucherOrder.setId(orderId);
voucherOrder.setUserId(UserHolder.getUser().getId());
voucherOrder.setVoucherId(voucherId);
flag = this.save(voucherOrder);
if (!flag) {
throw new RuntimeException("创建秒杀券订单失败");
}
return Result.ok(orderId);
}

浙公网安备 33010602011771号