Search in sources :

Example 1 with SeckillOrder

use of com.whoiszxl.entity.SeckillOrder in project shopzz by whoiszxl.

the class QueuedPlaceOrderServiceImpl method handlePlaceOrderTask.

@Override
@Transactional
public void handlePlaceOrderTask(SeckillPlaceOrderDTO seckillPlaceOrderDTO) {
    try {
        // 再次校验秒杀活动与秒杀商品的有效性
        boolean allowFlag = checkSeckill(seckillPlaceOrderDTO.getSeckillId());
        AssertUtils.isTrue(allowFlag, "秒杀活动校验失败");
        allowFlag = checkSeckillItem(seckillPlaceOrderDTO.getSeckillItemId());
        AssertUtils.isTrue(allowFlag, "秒杀商品校验失败");
        // 缓存中获取秒杀item,并将缓存中的库存设置上
        SeckillItem seckillItem = seckillItemService.getById(seckillPlaceOrderDTO.getSeckillItemId());
        // 进行库存实际扣减,因为通过token已经拦截了一次,可以直接进行数据库扣减,而不用走缓存扣减一次了
        boolean subDbFlag = seckillItemService.subDbStock(seckillPlaceOrderDTO.getSeckillItemId(), seckillPlaceOrderDTO.getQuantity());
        AssertUtils.isTrue(subDbFlag, "库存扣减失败");
        // 订单持久化
        SeckillOrder seckillOrder = buildSeckillOrder(seckillItem, seckillPlaceOrderDTO, seckillPlaceOrderDTO.getMemberId());
        boolean saveFlag = seckillOrderService.save(seckillOrder);
        if (!saveFlag) {
            ExceptionCatcher.catchValidateEx(ResponseResult.buildError("下单失败"));
        }
        // 如果taskKey的值为0,则说明还没执行完成,则设置为1
        Object taskValueObj = redisUtils.getObj(RedisKeyPrefixConstants.TASK_SECKILL_PLACE_ORDER_MQ + seckillPlaceOrderDTO.getTaskKey());
        if ("0".equals(taskValueObj)) {
            redisUtils.set(RedisKeyPrefixConstants.TASK_SECKILL_PLACE_ORDER_MQ + seckillPlaceOrderDTO.getTaskKey(), "1");
        }
        // 将订单ID设置到Redis中
        redisUtils.setEx(RedisKeyPrefixConstants.TASK_SECKILL_PLACE_ORDER_MQ_ORDER_ID + seckillPlaceOrderDTO.getTaskKey(), seckillOrder.getId().toString(), 24, TimeUnit.HOURS);
        log.info("handlePlaceOrderTask|MQ消费秒杀订单任务处理完成|{}", seckillPlaceOrderDTO);
    } catch (Exception e) {
        // 发生异常,设置为-1
        Object taskValueObj = redisUtils.getObj(RedisKeyPrefixConstants.TASK_SECKILL_PLACE_ORDER_MQ + seckillPlaceOrderDTO.getTaskKey());
        if (taskValueObj != null && "0".equals(taskValueObj)) {
            redisUtils.set(RedisKeyPrefixConstants.TASK_SECKILL_PLACE_ORDER_MQ + seckillPlaceOrderDTO.getTaskKey(), "-1");
        }
        log.info("handlePlaceOrderTask|MQ消费秒杀订单任务处理发生异常|{}", seckillPlaceOrderDTO, e);
        ExceptionCatcher.catchValidateEx(ResponseResult.buildError("下单失败"));
    }
}
Also used : SeckillItem(com.whoiszxl.entity.SeckillItem) SeckillOrder(com.whoiszxl.entity.SeckillOrder) Transactional(org.springframework.transaction.annotation.Transactional)

Example 2 with SeckillOrder

use of com.whoiszxl.entity.SeckillOrder in project shopzz by whoiszxl.

the class QueuedPlaceOrderServiceImpl method buildSeckillOrder.

private SeckillOrder buildSeckillOrder(SeckillItem seckillItem, SeckillPlaceOrderDTO seckillPlaceOrderDTO, Long memberId) {
    SeckillOrder seckillOrder = new SeckillOrder();
    seckillOrder.setId(idWorker.nextId());
    seckillOrder.setMemberId(memberId);
    seckillOrder.setSkuName(seckillItem.getSkuName());
    seckillOrder.setSkuPrice(seckillItem.getSkuPrice());
    seckillOrder.setSeckillPrice(seckillItem.getSeckillPrice());
    seckillOrder.setFinalPayAmount(seckillItem.getSeckillPrice().multiply(new BigDecimal(seckillPlaceOrderDTO.getQuantity())));
    seckillOrder.setSeckillId(seckillPlaceOrderDTO.getSeckillId());
    seckillOrder.setSeckillItemId(seckillPlaceOrderDTO.getSeckillItemId());
    seckillOrder.setBuyQuantity(seckillPlaceOrderDTO.getQuantity());
    seckillOrder.setStatus(SeckillOrderStatusEnum.NOT_PAY.getCode());
    return seckillOrder;
}
Also used : SeckillOrder(com.whoiszxl.entity.SeckillOrder) BigDecimal(java.math.BigDecimal)

Example 3 with SeckillOrder

use of com.whoiszxl.entity.SeckillOrder in project shopzz by whoiszxl.

the class DefaultPlaceOrderServiceImpl method buildSeckillOrder.

private SeckillOrder buildSeckillOrder(SeckillItem seckillItem, SeckillOrderSubmitCommand seckillOrderSubmitCommand) {
    SeckillOrder seckillOrder = new SeckillOrder();
    seckillOrder.setId(idWorker.nextId());
    seckillOrder.setMemberId(AuthUtils.getMemberId());
    seckillOrder.setSkuName(seckillItem.getSkuName());
    seckillOrder.setSkuPrice(seckillItem.getSkuPrice());
    seckillOrder.setSeckillPrice(seckillItem.getSeckillPrice());
    seckillOrder.setFinalPayAmount(seckillItem.getSeckillPrice().multiply(new BigDecimal(seckillOrderSubmitCommand.getQuantity())));
    seckillOrder.setSeckillId(seckillOrderSubmitCommand.getSeckillId());
    seckillOrder.setSeckillItemId(seckillOrderSubmitCommand.getSeckillItemId());
    seckillOrder.setBuyQuantity(seckillOrderSubmitCommand.getQuantity());
    return seckillOrder;
}
Also used : SeckillOrder(com.whoiszxl.entity.SeckillOrder) BigDecimal(java.math.BigDecimal)

Example 4 with SeckillOrder

use of com.whoiszxl.entity.SeckillOrder in project shopzz by whoiszxl.

the class DefaultPlaceOrderServiceImpl method doPlaceOrder.

@Override
public Long doPlaceOrder(Long memberId, SeckillOrderSubmitCommand seckillOrderSubmitCommand) {
    boolean allowFlag = checkSeckill(seckillOrderSubmitCommand.getSeckillId());
    AssertUtils.isTrue(allowFlag, "秒杀活动校验失败");
    allowFlag = checkSeckillItem(seckillOrderSubmitCommand.getSeckillItemId());
    AssertUtils.isTrue(allowFlag, "秒杀商品校验失败");
    // 缓存中获取秒杀item,并将缓存中的库存设置上
    SeckillItemCache seckillItemCache = seckillItemCachedService.getCachedSeckillItem(seckillOrderSubmitCommand.getSeckillItemId(), null);
    putStockToItem(seckillItemCache.getSeckillItem());
    SeckillItem seckillItem = seckillItemCache.getSeckillItem();
    boolean preSubCacheFlag = false;
    try {
        // 进行库存预扣减
        preSubCacheFlag = stockCacheService.subCacheStock(seckillOrderSubmitCommand.getSeckillItemId(), seckillOrderSubmitCommand.getQuantity());
        AssertUtils.isTrue(preSubCacheFlag, "库存预扣减失败");
        // 进行库存实际扣减
        boolean subDbFlag = seckillItemService.subDbStock(seckillOrderSubmitCommand.getSeckillItemId(), seckillOrderSubmitCommand.getQuantity());
        AssertUtils.isTrue(subDbFlag, "库存扣减失败");
        // 持久化订单
        SeckillOrder seckillOrder = buildSeckillOrder(seckillItem, seckillOrderSubmitCommand);
        boolean saveFlag = seckillOrderService.save(seckillOrder);
        if (!saveFlag) {
            ExceptionCatcher.catchValidateEx(ResponseResult.buildError("下单失败"));
        }
        return seckillOrder.getId();
    } catch (Exception e) {
        // 如果预下单成功了,回滚缓存里的库存数量
        if (preSubCacheFlag) {
            boolean recoverFlag = stockCacheService.addCacheStock(seckillOrderSubmitCommand.getSeckillItemId(), seckillOrderSubmitCommand.getQuantity());
            if (!recoverFlag) {
                log.error("预扣减库存恢复失败,用户ID:{}, 秒杀商品ID:{}, 秒杀数量:{}", memberId, seckillOrderSubmitCommand.getSeckillItemId(), seckillOrderSubmitCommand.getQuantity());
            }
            ExceptionCatcher.catchValidateEx(ResponseResult.buildError("下单失败"));
        }
    }
    return null;
}
Also used : SeckillItem(com.whoiszxl.entity.SeckillItem) SeckillOrder(com.whoiszxl.entity.SeckillOrder) SeckillItemCache(com.whoiszxl.cqrs.cache.SeckillItemCache)

Aggregations

SeckillOrder (com.whoiszxl.entity.SeckillOrder)4 SeckillItem (com.whoiszxl.entity.SeckillItem)2 BigDecimal (java.math.BigDecimal)2 SeckillItemCache (com.whoiszxl.cqrs.cache.SeckillItemCache)1 Transactional (org.springframework.transaction.annotation.Transactional)1