rocketmq-producer之发送事物消息

rocketmq支持普通消息、顺序消息,此外,还支持事物消息。实现方式是将一个大事务拆分成多个小事物异步执行,事物消息在其中起着桥梁作用。

这里写图片描述

rocketmq在发送事物消息时,会先发送一个prepared消息,返回消息所在地址。然后再执行本地事物,根据事物执行结果去更新prepared消息状态。消息接收者只能消费消息集群中消息状态为已提交的消息。

事物消息demo:

TransactionMQProducer producer = new TransactionMQProducer("unique_group_name");
TransactionCheckListener transactionCheckListener = new TransactionCheckListenerImpl();
producer.setTransactionCheckListener(transactionCheckListener);
TransactionExecuterImpl tranExecuter = new TransactionExecuterImpl();
producer.start();
Message msg =new Message(......);
SendResult sendResult = producer.sendMessageInTransaction(msg, tranExecuter, null);

当确认消息发送失败时,rocketmq会定期扫描消息集群中的事物消息,如果发现了Prepared消息,它会向消息发送者确认,如果此时事物执行成功了是回滚还是继续发送确认消息?rocketmq会调用TransactionCheckListener 的实现类来做出相应的操作。

TransactionExecuterImpl –>本地事物的处理逻辑

发送事物消息源码(伪代码)

public TransactionSendResult sendMessageInTransaction(.....)  {
    // 1.发送消息
    SendResult sendResult = this.send(msg);
    LocalTransactionState localTransactionState = LocalTransactionState.UNKNOW;
    switch (sendResult.getSendStatus()) {
    case SEND_OK: {
        // 2.如果消息发送成功,处理与消息关联的本地事务单元
        localTransactionState = tranExecuter.executeLocalTransactionBranch(msg, arg);
        }
    // 3.结束事务
    this.endTransaction(sendResult, localTransactionState, localException);
}

本地事物状态LocalTransactionState: 
COMMIT_MESSAGE, 
ROLLBACK_MESSAGE, 
UNKNOW

 public void endTransaction(SendResult sendResult, LocalTransactionState localTransactionState, ......){

       final String brokerAddr = this.mQClientFactory.findBrokerAddressInPublish(sendResult.getMessageQueue().getBrokerName());
       EndTransactionRequestHeader requestHeader = new EndTransactionRequestHeader();

       switch (localTransactionState) {
            case COMMIT_MESSAGE:
                requestHeader.setCommitOrRollback(MessageSysFlag.TransactionCommitType);
                break;
            case ROLLBACK_MESSAGE:
                requestHeader.setCommitOrRollback(MessageSysFlag.TransactionRollbackType);
                break;
            case UNKNOW:
                requestHeader.setCommitOrRollback(MessageSysFlag.TransactionNotType);
                break;
            default:
                break;
        }

        this.mQClientFactory.getMQClientAPIImpl().endTransactionOneway(brokerAddr, requestHeader, ......);
    }

endTransaction从sendResult中获取消息地址,将请求发送至broker,根据localTransactionState更新事物消息的最终状态。 
如果endTransaction方法执行失败,导致数据没有发送到broker,broker会有回查线程定时(默认1分钟)扫描每个存储事务状态的表格文件,如果是已经提交或者回滚的消息直接跳过,如果是TransactionNotType状态则会向Producer发起CheckTransaction请求,Producer会调用DefaultMQProducerImpl.checkTransactionState()方法来处理broker的定时回调请求,而checkTransactionState会调用我们的事务设置的决断方法,最后调用endTransactionOneway让broker来更新消息的最终状态。

发送事物消息时,groupname必须设置,回查时会根据group随机选择一台producer。

转载于:https://blog.csdn.net/qq_36569036/article/details/53448142

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
RocketMQ是一个开源的分布式消息中间件,它具有高吞吐量、高可用性、可伸缩性和可靠性的特点。RocketMQ提供了多种语言的客户端,其中包括了针对Spring Boot的RocketMQ启动器(starter)。 RocketMQ的Spring Boot启动器是一个用于集成RocketMQ和Spring Boot的依赖项。通过添加该启动器,我们可以方便地在Spring Boot项目中使用RocketMQ。 要使用rocketmq-spring-boot-starter,您需要完成以下步骤: 1. 在您的项目的pom.xml文件中添加以下依赖项: ```xml <dependency> <groupId>org.apache.rocketmq</groupId> <artifactId>rocketmq-spring-boot-starter</artifactId> <version>版本号</version> </dependency> ``` 请注意,您需要将“版本号”替换为您想要使用的RocketMQ Spring Boot Starter的版本号。 2. 在您的应用程序的配置文件(例如application.properties或application.yml)中添加RocketMQ的相关配置。您可以根据您的需求配置以下属性: - rocketmq.name-server:RocketMQ的Name Server地址。 - rocketmq.producer.group:生产者组的名称。 - rocketmq.consumer.group:消费者组的名称。 - rocketmq.consumer.topics:要订阅的主题列表。 3. 在您的Spring Boot应用程序中使用RocketMQ的相关注解来发送和接收消息。例如,您可以使用`@RocketMQMessageListener`注解来监听RocketMQ消息,并使用`@RocketMQTransactionListener`注解来处理事务消息。 通过使用rocketmq-spring-boot-starter,您可以方便地在Spring Boot项目中集成RocketMQ,并使用RocketMQ的各种功能,如发送普通消息发送和接收顺序消息发送和接收定时消息等。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值