下订单代码

    @Override
    @Transactional
    public String create(OrderVo orderVo) throws ExecutionException, InterruptedException {

        //因为请求是存于ThreadLocal的,在主线程的请求想要给子线程使用,就需拿出来给下面的子线程共享
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();

        //1.根据地址id调用地址服务查询地址详情
        CompletableFuture<AddressVo> addressFuture = CompletableFuture.supplyAsync(() -> {
            RequestContextHolder.setRequestAttributes(requestAttributes);
            return addressService.getAddressVoById(orderVo.getAid());
        }, ShopExcutors.getExecutor());


        //2.根据商品id查询商品详情和购物车数量
        CompletableFuture<UserCarVo> carFuture = CompletableFuture.supplyAsync(() -> {
            RequestContextHolder.setRequestAttributes(requestAttributes);
            UserCarVo userCar = carService.getUserCar(orderVo.getSelectGid());
            log.debug("userCar:{}",userCar);
            return userCar;
        }, ShopExcutors.getExecutor());

//        感觉不需要吧?
        carFuture.get();

        //3.在2的基础上锁库存
        CompletableFuture<Boolean> stockFuture = carFuture.thenApplyAsync((userCarVo) -> {
            RequestContextHolder.setRequestAttributes(requestAttributes);
            List<StockVo> stockVoList = new ArrayList();
            for (StoreCarVo storeCarVo : userCarVo.getStoreCarVoList()) {
                for (CarVo carVo : storeCarVo.getCarVoList()) {
                    StockVo stockVo = new StockVo();
                    stockVo.setGid(carVo.getGid());
                    stockVo.setCount(carVo.getCount());
                    stockVoList.add(stockVo);
                }
            }
            return stockService.lockStock(stockVoList);
        }, ShopExcutors.getExecutor());


        Boolean aBoolean = stockFuture.get();
        if (!aBoolean) {
            throw new BusinessException("扣减库存失败", 3001);
        }

        //4.订单,需要等123都完成
        CompletableFuture<Void> future = CompletableFuture.allOf(addressFuture, stockFuture);
        future.get();// 地址任务和库存任务全部执行完


        // 5.先获取登录用户
        UserVo userVo = loginInterceptor.get();

        // 6.创建订单ID(yyyMMdd+用户ID后四位+4位随机数+流水号(唯一))
        String orderId = orderUtils.createOrderId(userVo.getId());

        // 7、获取表的索引
        Integer tabIndex = orderDynamicDatasourceInterceptor.get();

        AddressVo addressVo = addressFuture.get();
        UserCarVo userCarVo = carFuture.get();


        // 8.封装订单数据,插入订单数据
        CompletableFuture<Void> orderFuture = CompletableFuture.runAsync(() -> {

            orderDynamicDatasourceInterceptor.setOrderDataSource(userVo); // 重新设置。

            OrderEntity orderEntity = new OrderEntity();
            orderEntity.setId(orderId);
            orderEntity.setUid(Integer.parseInt(userVo.getId()));
            orderEntity.setAddress(addressVo.getAddress());
            orderEntity.setPhone(addressVo.getPhone());
            orderEntity.setName(addressVo.getName());
            orderEntity.setStatus(1); // 1
            orderEntity.setTotalPrice(userCarVo.getTotalPrice());
            orderEntity.setCreateTime(new Date());
            orderEntity.setPayType(orderVo.getPayType());
            log.debug("orderEntity:{}", orderEntity);
            int order = orderMapper.createOrder(orderEntity, tabIndex);
            log.debug("order:{}", order);
        }, ShopExcutors.getExecutor());

// 9、插入订单详情
        CompletableFuture<Void> orderDetailfuture = CompletableFuture.runAsync(() -> {
            orderDynamicDatasourceInterceptor.setOrderDataSource(userVo); // 重新设置
            List<OrderDetailEntity> odList = new ArrayList<>();
            for (StoreCarVo storeCarVo : userCarVo.getStoreCarVoList()) {
                for (CarVo carVo : storeCarVo.getCarVoList()) {
                    // 把用户购买的数据封装到订单闲情中
                    OrderDetailEntity odEntity = new OrderDetailEntity();
                    odEntity.setCount(carVo.getCount());
                    odEntity.setGdesc(carVo.getGoodsVo().getGdesc());
                    odEntity.setGid(carVo.getGid());
                    odEntity.setGprice(carVo.getGoodsVo().getGprice());
                    odEntity.setGname(carVo.getGoodsVo().getGname());
                    odEntity.setGurl(carVo.getGoodsVo().getGoodsPngList().get(0).getUrl());
                    odEntity.setOid(orderId);
                    odEntity.setSid(storeCarVo.getStoreVo().getId()); //
                    odEntity.setSubTotal(carVo.getSubTotal());
                    odList.add(odEntity);
                }
            }
            // 批量插入订单详情
            int odCount = orderMapper.batchInsertOrderDetail(odList, tabIndex);
            log.debug("odCount:{}", odCount);
        }, ShopExcutors.getExecutor());

        // 订单任务和订单详情任务全部执行完后再返回订单ID
        CompletableFuture<Void> odFulure = CompletableFuture.allOf(orderFuture, orderDetailfuture);
        odFulure.get(); // 阻塞


        // 清空购物车
//        carService.clearUserCar(userVo.getId(),orderVo.getSelectGid());

        return orderId;
    }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
订单锁库逻辑代码的实现需要考虑以下几个步骤: 1. 判断库存是否充足:在下订单之前,需要判断商品的库存是否足够,如果库存不足,则不能下订单。 2. 更新库存:如果库存充足,则需要更新库存,将库存数量减去订单中商品的数量。 3. 锁定库存:在更新库存的同时,需要将库存锁定,避免其他用户在此期间购买该商品导致库存不足。可以采用数据库事务的方式来实现库存锁定。 下面是一个简单的订单锁库逻辑代码示例(使用Java语言和MySQL数据库): ``` // 检查库存是否充足 int stock = getStock(productId); if (stock < quantity) { throw new RuntimeException("库存不足"); } // 更新库存和锁定库存 Connection conn = null; try { conn = getConnection(); // 开启事务 conn.setAutoCommit(false); // 更新库存 updateStock(conn, productId, stock - quantity); // 锁定库存 lockStock(conn, productId, quantity); // 提交事务 conn.commit(); } catch (Exception e) { // 回滚事务 if (conn != null) { conn.rollback(); } throw e; } finally { // 关闭连接 if (conn != null) { conn.close(); } } // 下订单 placeOrder(productId, quantity); ``` 其中,`getStock`方法用于获取商品的库存数量,`updateStock`方法用于更新商品的库存数量,`lockStock`方法用于锁定商品的库存数量,`placeOrder`方法用于下订单。在代码中,使用了事务来保证更新库存和锁定库存的原子性操作。如果在更新库存或锁定库存的过程中出现异常,则会回滚事务,避免数据不一致。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值