全站最硬核 百万字强肝RocketMq源码 火热更新中~(一百零五)事务消息

事务消息

并不是实际消息可回退,而是在实际发送消息之前,有一个预消费的动作。

举例:

比如我准备回家,但是我本身没有钥匙,所以我需要确定家里有人,不然的话我人跑到家才发现家里没人,这不是白跑了吗?所以我先打个电话问问家人在不在家,如果在家,我才出发回家。

实际回家,和打电话 是两件事

也就是说预消费和真实的消费,本身还是不一样的。

图解:请添加图片描述
代码:

consumer不需要特殊处理,就不写了

producer是需要专为事务消息做改造的:

ProducerServiceImpl:

@Service
public class ProducerServiceImpl implements ProducerService {

    private TransactionMQProducer transactionMQProducer = null;
    
    
    @PostConstruct
    public void initTransactionMQProducer() {
        transactionMQProducer = new TransactionMQProducer("transactionGroup");
        transactionMQProducer.setNamesrvAddr("localhost:9876");
        transactionMQProducer.setRetryTimesWhenSendFailed(1);

        try {
            transactionMQProducer.start();
        } catch (MQClientException e) {
            e.printStackTrace();
        }
        System.out.println("transactionMQProducer成功");
    }
    
    
    /**
     * 发送事务消息
     *
     * @param topic
     * @param tags
     * @param content
     * @return
     */
    @Override
    public SendResult sendTranscationMsg(String topic, String tags, String content) {
        transactionMQProducer.setTransactionListener(new TransactionListener() {
            @Override
            public LocalTransactionState executeLocalTransaction(Message msg, Object arg) {
                // 预处理
                // 比如说
                // 设置一个业务场景 提交消息,确认订单
                // 生成订单有个前提  就是商品id存在
                Map<String, String> properties = msg.getProperties();
                String commodityId = properties.get("commodityId");
                // 如果商品id不合法,说明无法生成订单
                // 合法就允许生成
                try {
                    // 实际去校验合法的时候,肯定是要查库或者查缓存的
                    boolean check = checkCommodityId(commodityId);
                    return check ? LocalTransactionState.COMMIT_MESSAGE : LocalTransactionState.ROLLBACK_MESSAGE;
                } catch (Exception e) {
                    return LocalTransactionState.UNKNOW;
                }
            }


            @Override
            public LocalTransactionState checkLocalTransaction(MessageExt msg) {
                // 预处理超时
                // 比如说我们认为重试次数为2时,就算失败
                if (2 == msg.getReconsumeTimes()) {
                    return LocalTransactionState.ROLLBACK_MESSAGE;
                }
                // 认为queueId为100则成功
                if (100 == msg.getQueueId()) {
                    return LocalTransactionState.COMMIT_MESSAGE;
                }
                return LocalTransactionState.ROLLBACK_MESSAGE;
            }
        });
        return null;
    }

    /**
     * 检验商品id是否合法
     *
     * @param commodityId
     * @return
     */
    private boolean checkCommodityId(String commodityId) {
        return true;
    }
  
    @PreDestroy
    public void shutDownProducer() {
        if (transactionMQProducer != null) {
            transactionMQProducer.shutdown();
        }
    }

模拟的是:

商品服务调用订单服务,订单服务去校验商品id是否合法,如果不合法,不消费。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值