GitHub user Bughue edited a discussion: Seata集成RocketMQ设计
## 背景 [https://github.com/apache/incubator-seata/issues/3752](https://link.zhihu.com/?target=https%3A//github.com/apache/incubator-seata/issues/3752) ## 设计 ### 前提 **seata的全局事务** seata目前全局事务是有两种方式的,一种是saga,另一种是二阶段。我们现在希望做的是把rocketmq的事务作为一个分支加入到二阶段全局事务里,事务里同时可以和AT TCC等分支。 **rocketmq的事务消息** rocketmq支持发送一个半消息(broker收到后暂不投递),然后执行本地事务,完成后通知broker是提交还是回滚这条消息(所以只涉及发送阶段一致性,消费阶段的一致性由重试和其他手动保证)  ### 总体设计思路 本次集成的能力重点在全局事务的一阶段,我们会提供一个SeataMQProducer,在里面将以下两个方法自动加入到全局事务中。其他方法会调用到原生父类进行,不会加入到全局事务。(原因是request/oneway/批量发送/指定selector的send等很多方法在原生里也不支持事务消息) ```text SendResult send(final Message msg) throws MQClientException, RemotingException, MQBrokerException, InterruptedException; SendResult send(final Message msg, final long timeout) throws MQClientException, RemotingException, MQBrokerException, InterruptedException; ``` ### 方案流程  ### 时序图(commit&rollback两种情况)   ### 一致性问题 参考上面的时序图,考虑以下的正常流程,发现有一致性问题难以解决: 1. TM发起全局事务 2. 注册rocketmq事务分支 3. 发送半消息 4. 执行本地事务(这里是直接返回unknown) 5. 上报rocketmq分支执行结果(目前看来TC对此只做记录,不会影响二阶段的决策) 6. (如果4和5成功)注册并上报其他事务分支 7. TM发起二阶段/全局事务超时 **seata分支已产生,但半消息未发送** 如果在\[3\]之前宕机了,消息未发送,seata的分支一阶段也会失败,这种情况下TC有可能发起回滚,但是在事务context里却没有messageid(无法通知mq的broker),这种情况下应该可以直接回滚成功(类似空回滚) **seata分支已产生,半消息已发送,但发送结果和message没有放入context中** 如果在\[2\]之后\[3\]之前宕机了,TC也会发起回滚,同样的context里也没有messageid,这种情况下有两个问题, 1. 对于seata的处理,类似消息未发送的情况,rollback应该允许成功,问题解决。 2. 对于broker的回查处理,我们如果一味的返回unknown,那消息将永远不可见,不commit也不rollback 对于问题2,如果拥有回查1阶段状态的能力是可以支持的,但目前现在RM没有这个能力,所以: - 要么改造RM,支持回查globalstatus - 要么在这种情况下直接当成失败(消息会rollback)。 会议讨论的结论是TC支持回查,前提是在发送消息时在头部加入xid。 但随之而来的还有一个问题,如果globalstatus查不到呢?这种情况现在看来是回滚或提交已经完成且通知broker了,但broker可能还没收到或者状态还没扭转,又发起了一次回查listener,忽略就可以。 ### 其他问题 **支持加入全局事务的producer方法**:目前只支持上述两个,其他的暂不考虑。 **使用切面还是直接编写SeataMqProducer**:直接写SeataMqProducer会更加好读和好维护,虽然在维护上也有其他成本,但是我们现在需要“代理”的方法少,这样做比代理类更加可控,影响范围也更加可控,不会带来额外影响。 GitHub link: https://github.com/apache/incubator-seata/discussions/6314 ---- This is an automatically sent email for dev@seata.apache.org. To unsubscribe, please send an email to: dev-unsubscr...@seata.apache.org --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@seata.apache.org For additional commands, e-mail: dev-h...@seata.apache.org