1.方法自身(this)调用问题,导致事务失效
非事务方法seckillVoucher()中调用的自身类的事务方法createVoucherOrder()。
解决办法:
ps:要加aspj依赖,同时在Application中开启@EnableAspectJAutoProxy(exposeProxy = true)
@Override public Result seckillVoucher(Long voucherId) { //1.判断优惠券ID是否存在 SeckillVoucher seckillVoucher = iSeckillVoucherService.getById(voucherId); //2.不存在,返回异常 if(seckillVoucher == null){ return Result.fail("优惠券不存在"); } //3.存在,判断秒杀是否开始 if(seckillVoucher.getBeginTime().isAfter(LocalDateTime.now())){ return Result.fail("秒杀未开始"); } //4.存在,判断秒杀是否结束 if(seckillVoucher.getEndTime().isBefore(LocalDateTime.now())){ return Result.fail("秒杀已结束"); } //5.库存为空,返回异常 if(seckillVoucher.getStock() < 1){ return Result.fail("库存不足"); } Long userId = UserHolder.getUser().getId();
/*----------这里调用-------------*/ synchronized (userId.toString().intern()){ return createVoucherOrder(voucherId); }
/*----------用这种-------------*/ synchronized (userId.toString().intern()){ return ((IVoucherOrderService)AopContext.currentProxy()).createVouch } } @Transactional public Result createVoucherOrder(Long voucherId){ //判断用户是否已经有优惠券 QueryWrapper<VoucherOrder> queryWrapper = new QueryWrapper<>(); queryWrapper.eq("user_id",UserHolder.getUser().getId()); queryWrapper.eq("voucher_id",voucherId); int record = this.count(); if(record > 0){ return Result.fail("this user have voucher"); } //6.库存不为空,新增数据,减库存 boolean success = iSeckillVoucherService.update() .setSql("stock = stock - 1") .eq("voucher_id", voucherId) .gt("stock",0) .update(); if(!success){ return Result.fail("库存不足"); } long orderId = redisWorker.nextId("order"); VoucherOrder voucherOrder = new VoucherOrder(); voucherOrder.setId(orderId); voucherOrder.setUserId(UserHolder.getUser().getId()); voucherOrder.setVoucherId(voucherId); save(voucherOrder); //返回订单ID return Result.ok(orderId); }
标签:事务,return,voucherOrder,seckillVoucher,生效,voucherId,Result,spring,fail From: https://www.cnblogs.com/cciscc/p/17082136.html