「分布式专题」RocketMQ 发送事务消息 事务消息的执行流程(代码演示)

30 篇文章 3 订阅
  1. 本地方法发送消息至borker
  2. borker 执行TransactionListener的方法。执行本地事务executeLocalTransaction
  3. 如果返回unkow状态,borker会回调checkLocalTransaction检查事务的结果,返回提交还是回滚
  4. borker设置消息对外可见,等待消费或主动推送

事务消息共有三种状态,提交状态、回滚状态、中间状态:

  • TransactionStatus.CommitTransaction: 提交事务,它允许消费者消费此消息。
  • TransactionStatus.RollbackTransaction: 回滚事务,它代表该消息将被删除,不允许被消费。
  • TransactionStatus.Unknown: 中间状态,它代表需要检查消息队列来确定状态。

事务的流程如下图简述

发送事务消息

代码演示

发送一个消息(第一步)

  rocketMQTemplate.sendMessageInTransaction("send_message_to_ipc",
                "ipo-system-notice-topic",
                MessageBuilder.withPayload(JSONUtil.toJsonStr(entity)).build(),
                null);

Borker回查本地事务并执行本地事务,根据本地事务返回commit还是rollback(第二三四步)

    @Component
    @RocketMQTransactionListener(txProducerGroup = "send_message_to_ipc")
    public static class SendMessageToIpcExecuteLocal implements RocketMQLocalTransactionListener {

        @Autowired
        TNoticeMapper tNoticeMapper;

        @Override
        public RocketMQLocalTransactionState executeLocalTransaction(Message msg, Object arg) {
            String body = new String((byte[]) msg.getPayload(), StandardCharsets.UTF_8);
            TNotice bean = JSONUtil.toBean(body, TNotice.class);
            bean.setType("1");
            
            // 本地事务
            return tNoticeMapper.insert(bean) != 0 ?
                    RocketMQLocalTransactionState.COMMIT
                    : RocketMQLocalTransactionState.ROLLBACK;
        }

        @Override
        public RocketMQLocalTransactionState checkLocalTransaction(Message msg) {
            return null;
        }
    }

等待消费者消费(第六步)。。

@Slf4j
@Component
@RocketMQMessageListener(topic = "ipo-system-notice-topic", consumerGroup = "ipc-system-notice-group")
public class MQSystemNoticeListener implements RocketMQListener<String>, RocketMQPushConsumerLifecycleListener {

    @Autowired
    IdUtils idUtils;
    @Autowired
    TCmNoticeMapper cmNoticeMapper;
    @Autowired
    TCmUserOrganMapper cmUserOrganMapper;

    @Override
    public void onMessage(String message) {
        List<TCmUserOrgan> organs = cmUserOrganMapper.selectList(null);
        TCmNotice notice = JSONUtil.toBean(message, TCmNotice.class);
        ArrayList<TCmNotice> list = new ArrayList<>();
        for (TCmUserOrgan organ : organs) {
            TCmNotice dto = new TCmNotice();
            dto.setId(idUtils.nextIdStr());
            dto.setTopic(notice.getTopic());
            dto.setContent(notice.getContent());
            dto.setType("1");
            dto.setStatus("1");
            dto.setOrganId(organ.getOrganId());
            dto.setUserId(organ.getUserId());
            list.add(dto);
        }
        cmNoticeMapper.saveBatch(list);
        log.info("保存系统消息成功:{}", message);
    }

    @Override
    public void prepareStart(DefaultMQPushConsumer consumer) {
        consumer.setMaxReconsumeTimes(5);
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值