本文共 10016 字,大约阅读时间需要 33 分钟。
我们这个ccm-mall工程,核心接口就是下订单接口,在之前的章节已经讲解过,该接口涉及了四个微服务server-user、server-goods、server-pay和server-order.本章节我们将该接口加入seata分布式事务,保证在异常情况下的数据一致性.
com.alibaba.cloud spring-cloud-alibaba-seata 2.2.0.RELEASE io.seata seata-spring-boot-starter io.seata seata-spring-boot-starter 1.2.0
seata: enabled: true application-id: ${ spring.application.name} tx-service-group: my_test_tx_group enable-auto-data-source-proxy: true config: type: nacos nacos: namespace: serverAddr: 47.96.131.185:8849 group: SEATA_GROUP userName: "nacos" password: "nacos" registry: type: nacos nacos: application: seata-server #seata服务端(TC)在nacos中的应用名称 server-addr: 47.96.131.185:8849 namespace: userName: "nacos" password: "nacos"
undo_log表sql脚本的位置:seata资源包路径:seata-1.2.0/script/client/at/db/mysql.sql
package com.ccm.server.order.service.impl;import com.alibaba.nacos.client.naming.utils.CollectionUtils;import com.ccm.common.exception.CustomerException;import com.ccm.common.exception.result.ResultSet;import com.ccm.server.order.config.OrderIdGenerator;import com.ccm.server.order.controller.req.PayOrderReq;import com.ccm.server.order.dao.mysql.domain.OrderInfo;import com.ccm.server.order.dao.mysql.domain.OrderSku;import com.ccm.server.order.dao.mysql.mapper.OrderInfoMapper;import com.ccm.server.order.dao.mysql.mapper.OrderSkuMapper;import com.ccm.server.order.feign.ServerGoodsFeign;import com.ccm.server.order.feign.ServerPayFeign;import com.ccm.server.order.feign.req.ReduceStockReq;import com.ccm.server.order.feign.vo.GoodsSkuVO;import com.ccm.server.order.service.OrderService;import io.seata.spring.annotation.GlobalTransactional;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import org.springframework.transaction.annotation.Transactional;import java.util.ArrayList;import java.util.List;import java.util.stream.Collectors;/** * @Description 订单业务层实现类 * @Author ccm * @CreateTime 2020/08/14 10:11 */@Servicepublic class OrderServiceImpl implements OrderService { @Autowired private OrderSkuMapper orderSkuMapper; @Autowired private OrderInfoMapper orderInfoMapper; @Autowired private ServerGoodsFeign serverGoodsFeign; @Autowired private OrderIdGenerator orderIdGenerator; @Autowired private ServerPayFeign serverPayFeign; @Override @GlobalTransactional @Transactional(rollbackFor = Exception.class) public void order(ListpayOrderReqList, Long userId) { //生成订单号 String orderId = orderIdGenerator.nextOrderId(); //获取商品的详细信息 ResultSet
> resultSet = serverGoodsFeign.selectByIdList(payOrderReqList.stream() .map(PayOrderReq::getSkuId) .collect(Collectors.toList())); List goodsSkuVOList = ResultSet.getFeignData(resultSet); if(CollectionUtils.isEmpty(goodsSkuVOList) || goodsSkuVOList.size()!=payOrderReqList.size()) { throw new CustomerException("商品不存在"); } //扣商品库存 List reduceStockReqList = payOrderReqList.stream() .map(t -> new ReduceStockReq(t.getSkuId(),t.getSkuNumber())) .collect(Collectors.toList()); ResultSet.getFeignData(serverGoodsFeign.reduceStock(reduceStockReqList)); //支付 BigDecimal totalMoney = new BigDecimal(0.0d); for(PayOrderReq payOrderReq:payOrderReqList) { for(GoodsSkuVO goodsSkuVO:goodsSkuVOList) { if(payOrderReq.getSkuId().equals(goodsSkuVO.getId())) { BigDecimal skuNumber = new BigDecimal(payOrderReq.getSkuNumber()); totalMoney = totalMoney.add(goodsSkuVO.getPrice().multiply(skuNumber)); break; } } } String flowingWaterId = ResultSet.getFeignData(serverPayFeign.pay(userId, totalMoney)); //主订单表插入数据 OrderInfo orderInfo = new OrderInfo(); orderInfo.setId(orderId); orderInfo.setAmountMoney(totalMoney); orderInfo.setStatus(1); orderInfo.setUserId(userId); orderInfo.setFlowingWaterId(flowingWaterId); orderInfoMapper.insert(orderInfo); //子订单表插入数据 ArrayList orderSkuList = new ArrayList<>(); payOrderReqList.forEach(payOrderReq -> { OrderSku orderSku = new OrderSku(); orderSku.setOrderId(orderId); orderSku.setSkuNumber(payOrderReq.getSkuNumber()); orderSku.setSkuId(payOrderReq.getSkuId()); for(GoodsSkuVO goodsSkuVO:goodsSkuVOList) { if(payOrderReq.getSkuId().equals(goodsSkuVO.getId())) { orderSku.setSkuMoney(goodsSkuVO.getPrice()); break; } } orderSkuList.add(orderSku); }); orderSkuMapper.insertList(orderSkuList); }}
购买一台苹果11和两台华为P30
package com.ccm.server.order.service.impl;import com.alibaba.nacos.client.naming.utils.CollectionUtils;import com.ccm.common.exception.CustomerException;import com.ccm.common.exception.result.ResultSet;import com.ccm.server.order.config.OrderIdGenerator;import com.ccm.server.order.controller.req.PayOrderReq;import com.ccm.server.order.dao.mysql.domain.OrderInfo;import com.ccm.server.order.dao.mysql.domain.OrderSku;import com.ccm.server.order.dao.mysql.mapper.OrderInfoMapper;import com.ccm.server.order.dao.mysql.mapper.OrderSkuMapper;import com.ccm.server.order.feign.ServerGoodsFeign;import com.ccm.server.order.feign.ServerPayFeign;import com.ccm.server.order.feign.req.ReduceStockReq;import com.ccm.server.order.feign.vo.GoodsSkuVO;import com.ccm.server.order.service.OrderService;import io.seata.spring.annotation.GlobalTransactional;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import org.springframework.transaction.annotation.Transactional;import java.util.ArrayList;import java.util.List;import java.util.stream.Collectors;/** * @Description 订单业务层实现类 * @Author ccm * @CreateTime 2020/08/14 10:11 */@Servicepublic class OrderServiceImpl implements OrderService { @Autowired private OrderSkuMapper orderSkuMapper; @Autowired private OrderInfoMapper orderInfoMapper; @Autowired private ServerGoodsFeign serverGoodsFeign; @Autowired private OrderIdGenerator orderIdGenerator; @Autowired private ServerPayFeign serverPayFeign; @Override @GlobalTransactional @Transactional(rollbackFor = Exception.class) public void order(ListpayOrderReqList, Long userId) { //生成订单号 String orderId = orderIdGenerator.nextOrderId(); //获取商品的详细信息 ResultSet
> resultSet = serverGoodsFeign.selectByIdList(payOrderReqList.stream() .map(PayOrderReq::getSkuId) .collect(Collectors.toList())); List goodsSkuVOList = ResultSet.getFeignData(resultSet); if(CollectionUtils.isEmpty(goodsSkuVOList) || goodsSkuVOList.size()!=payOrderReqList.size()) { throw new CustomerException("商品不存在"); } //扣商品库存 List reduceStockReqList = payOrderReqList.stream() .map(t -> new ReduceStockReq(t.getSkuId(),t.getSkuNumber())) .collect(Collectors.toList()); ResultSet.getFeignData(serverGoodsFeign.reduceStock(reduceStockReqList)); //支付 BigDecimal totalMoney = new BigDecimal(0.0d); for(PayOrderReq payOrderReq:payOrderReqList) { for(GoodsSkuVO goodsSkuVO:goodsSkuVOList) { if(payOrderReq.getSkuId().equals(goodsSkuVO.getId())) { BigDecimal skuNumber = new BigDecimal(payOrderReq.getSkuNumber()); totalMoney = totalMoney.add(goodsSkuVO.getPrice().multiply(skuNumber)); break; } } } String flowingWaterId = ResultSet.getFeignData(serverPayFeign.pay(userId, totalMoney)); //主订单表插入数据 OrderInfo orderInfo = new OrderInfo(); orderInfo.setId(orderId); orderInfo.setAmountMoney(totalMoney); orderInfo.setStatus(1); orderInfo.setUserId(userId); orderInfo.setFlowingWaterId(flowingWaterId); orderInfoMapper.insert(orderInfo); //子订单表插入数据 ArrayList orderSkuList = new ArrayList<>(); payOrderReqList.forEach(payOrderReq -> { OrderSku orderSku = new OrderSku(); orderSku.setOrderId(orderId); orderSku.setSkuNumber(payOrderReq.getSkuNumber()); orderSku.setSkuId(payOrderReq.getSkuId()); for(GoodsSkuVO goodsSkuVO:goodsSkuVOList) { if(payOrderReq.getSkuId().equals(goodsSkuVO.getId())) { orderSku.setSkuMoney(goodsSkuVO.getPrice()); break; } } orderSkuList.add(orderSku); }); orderSkuMapper.insertList(orderSkuList); int i = 1/0; }}
购买一台苹果11和两台华为P30
您的点赞、收藏、转发和关注是我持续创作的动力!
源码地址:
转载地址:http://butli.baihongyu.com/