Spring Cloud Alibaba学习笔记(14) - Spring Cloud Stream + RocketMQ实现分布式事务

发送消息

Spring消息编程模型下,使用RocketMQ收发消息 一文中,发送消息使用的是RocketMQTemplate类.
在集成了Spring Cloud Stream之后,我们可以使用Source实现消息的发送,代码如下

private final Source source;
......
source.output().send(
                MessageBuilder
                        .withPayload(Demo.builder().demoId(1).remark("哈哈哈").build())
                        .setHeader(RocketMQHeaders.TRANSACTION_ID, UUID.randomUUID().toString())
                        .setHeader("comment", JSON.toJSONString(forObject))
                        .build()
        );

在使用rocketMQTemplate类时,sendMessageInTransaction方法的第四个参数可以帮助我们传递对象,source接口的send方法没有多余参数,所以我们利用MessageBuilder将对象信息放在消息头里面.因为setHeader只能传递字符串,所以我们将对象转换为Json字符串,然后在处理本地事务从消息头中取出来,转换回来就可以了.

修改配置

在使用rocketMQTemplate类时,我们使用sendMessageInTransactiontxProducerGroup参数设置txProducerGroup信息,在引入了Spring Cloud Stream之后,我们在配置文件中配置该信息.配置如下

spring:
  cloud:
    stream:
      rocketmq:
        binder:
          name-server: 127.0.0.1:9876
        bindings:
          output:
            producer:
              transactional: true
              # txProducerGroup
              group: test-stream-rocketmq-transactional
      bindings:
        # 生产者
        output:
          # 指定topic
          destination: test-topic

本地业务处理

import com.alibaba.fastjson.JSON;
import com.example.study01.domain.dto.DemoComment;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.spring.annotation.RocketMQTransactionListener;
import org.apache.rocketmq.spring.core.RocketMQLocalTransactionListener;
import org.apache.rocketmq.spring.core.RocketMQLocalTransactionState;
import org.apache.rocketmq.spring.support.RocketMQHeaders;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHeaders;

@Slf4j
@RocketMQTransactionListener(txProducerGroup = "test-stream-rocketmq-transactional")
public class demoTransactionalListener implements RocketMQLocalTransactionListener {
    /**
     * 处理本地事务
     */
    @Override
    public RocketMQLocalTransactionState executeLocalTransaction(Message message, Object arg) {
        // 消息头
        MessageHeaders headers = message.getHeaders();
        String transactionalId = (String) headers.get(RocketMQHeaders.TRANSACTION_ID);
        DemoComment comment = JSON.parseObject(headers.get("comment").toString(), DemoComment.class);

        try {
            log.info("1111111");
            // 本地业务
            return RocketMQLocalTransactionState.COMMIT;
        } catch (Exception e) {
            return RocketMQLocalTransactionState.ROLLBACK;
        }
    }

    /**
     * 若在本地事务执行过程中缺少二次确认消息或生产者处于等待状态
     * MQ Server将向同一组中的每个生产者发送检查消息
     */
    @Override
    public RocketMQLocalTransactionState checkLocalTransaction(Message message) {
        log.info("222222");
        try {
            // 检查业务
            return RocketMQLocalTransactionState.COMMIT;
        } catch (Exception e) {
            return RocketMQLocalTransactionState.ROLLBACK;
        }
    }
}
posted @ 2019-10-26 13:02  夜的那种黑丶  阅读(4333)  评论(0编辑  收藏  举报