springboot 使用rocketmq实现简单的TCC

商品微服务

商品扣减库存请求体

java 复制代码
@Data
public class GoodsTccRequest {

    private List<Integer> skuIds;//商品售卖id

    private List<Integer> quantitys;//数量

    private String orderId;//订单号
}

商品TCC service

java 复制代码
public interface GoodsTccService {

    /**
     * 订单feign调用扣减库存时使用
     * */
    Integer tryStock(GoodsTccRequest request);//生成冻结库存记录,商品库存=商品库存-冻结库存,冻结库存状态=try

    /**
     * 监听MQ调用该方法,修改冻结状态
     * */
    Integer commitStock(String orderId);//冻结库存状态=commit


    /**
     * 监听MQ调用该方法,把冻结的库存加上去
     * */
    Integer cancelStock(String orderId);//冻结库存状态=cancle,商品库存=商品库存+冻结库存
}

tcc相关的监听器

java 复制代码
@Slf4j
@Service
@RocketMQMessageListener(consumerGroup = "goods_service_stock", topic = "order_create",messageModel= CLUSTERING,consumeThreadMax = 1)//"goods_change"
public class GoodsTccStockListener implements RocketMQListener<String>{

    @Resource
    private GoodsTccService goodsTccService;


    /*
    *监听商品tcc,执行tcc commit或者cancel
    * **/
    @Override
    public void onMessage(String body) {
        log.info("商品库存监听MQ消费 body {} ",body);

        JSONObject jsonObject = JSON.parseObject(body);
        String orderId = jsonObject.getString("orderId");
        String result = jsonObject.getString("result");
        if(result.equals("commit")){
            goodsTccService.commitStock(orderId);
        }else  if(result.equals("cancel")){
            goodsTccService.cancelStock(orderId);
        }
    }
}

订单服务

商品微服务feign

java 复制代码
public interface GoodsTccFeign {

    /**
     * 订单feign调用扣减库存时使用
     * */
    @PostMapping("/goods/stock/reduce")
    Integer tryStock(GoodsTccRequest request);//生成冻结库存记录,商品库存=商品库存-冻结库存,冻结库存状态=try
}

mq发送,用于最终一致性,要么cancel,要么commit

java 复制代码
@Slf4j
@Component
public class MessageGoodsTccSendProducer {

    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    /**
     * 异步发送消息
     * @param orderId 订单id
     * @param result 请求结果 ("commit","cancel")
     */
    public void asyncSend(String orderId,String result){
        JSONObject obj = new JSONObject();
        obj.put("orderId",orderId);
        obj.put("result",result);
        Message<String> message = MessageBuilder.withPayload(obj.toJSONString()).build();
        // 异步发送消息
        rocketMQTemplate.asyncSend("order_create", message, new SendCallback() {
            @Override
            public void onSuccess(SendResult sendResult) {
                log.info("消息发送Producer, message为:{}, 成功。{}", message.getPayload(), JSONObject.toJSONString(sendResult));
            }

            @Override
            public void onException(Throwable throwable) {
                log.error("消息发送Producer失败,messageId为:{}, 异常:{}", message.getPayload(), throwable.getMessage());
            }
        }, 5000, 0);
    }
}

下单controller

java 复制代码
@RestController
@RequestMapping("/order")
public class OrderCreateController {

    GoodsTccFeign goodsTccFeign;

    MessageGoodsTccSendProducer messageGoodsTccSendProducer;

    @RequestMapping("/create")
    public Map getCanGotoActivityTag(@RequestParam("skuIds") List<Integer> skuids, @RequestParam("quantitys")List<Integer> quantitys){
        GoodsTccRequest goodsTccRequest = new GoodsTccRequest();
        goodsTccRequest.setSkuIds(skuids);
        goodsTccRequest.setSkuIds(quantitys);
        String orderId = UUID.randomUUID().toString().replace("-","");
        goodsTccRequest.setOrderId(orderId);
        //冻结库存
        goodsTccFeign.tryStock(goodsTccRequest);

        //生成订单

        //如果一切正常
        String result = "commit";

        //如果异常
        //result = "cancel";

        //发送消息
        messageGoodsTccSendProducer.asyncSend(orderId,result);
        Map orderMap = new HashMap<>();
        return orderMap;
    }

}
相关推荐
爱吃土豆的马铃薯ㅤㅤㅤㅤㅤㅤㅤㅤㅤ5 分钟前
idea 弹窗 delete remote branch origin/develop-deploy
java·elasticsearch·intellij-idea
Code成立8 分钟前
《Java核心技术 卷I》用户图形界面鼠标事件
java·开发语言·计算机外设
Xiao Fei Xiangζั͡ޓއއ28 分钟前
一觉睡醒,全世界计算机水平下降100倍,而我却精通C语言——scanf函数
c语言·开发语言·笔记·程序人生·面试·蓝桥杯·学习方法
记录无知岁月30 分钟前
【MATLAB】目标检测初探
开发语言·yolo·目标检测·matlab·yolov3·yolov2
鸽鸽程序猿32 分钟前
【算法】【优选算法】二分查找算法(下)
java·算法·二分查找算法
远望清一色44 分钟前
基于MATLAB身份证号码识别
开发语言·图像处理·算法·matlab
遇见你真好。1 小时前
自定义注解进行数据脱敏
java·springboot
NMBG221 小时前
[JAVAEE] 面试题(四) - 多线程下使用ArrayList涉及到的线程安全问题及解决
java·开发语言·面试·java-ee·intellij-idea
Py小趴1 小时前
Python自学之Colormaps指南
开发语言·python·数据可视化
晒足以百八十1 小时前
基于Python 和 pyecharts 制作招聘数据可视化分析大屏
开发语言·python·信息可视化