Replies: 2 comments 1 reply
-
rocketmq 目前sdk 有两个大版本,协议上不同 一个是remoting的版本。https://github.com/apache/rocketmq/blob/develop/example/src/main/java/org/apache/rocketmq/example/transaction/TransactionProducer.java 本次主要是先支持第一个对吧 |
Beta Was this translation helpful? Give feedback.
1 reply
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
背景
https://github.com/apache/incubator-seata/issues/3752
设计
前提
seata的全局事务
seata目前全局事务是有两种方式的,一种是saga,另一种是二阶段。我们现在希望做的是把rocketmq的事务作为一个分支加入到二阶段全局事务里,事务里同时可以和AT TCC等分支。
rocketmq的事务消息
rocketmq支持发送一个半消息(broker收到后暂不投递),然后执行本地事务,完成后通知broker是提交还是回滚这条消息(所以只涉及发送阶段一致性,消费阶段的一致性由重试和其他手动保证)
总体设计思路
本次集成的能力重点在全局事务的一阶段,我们会提供一个SeataMQProducer,在里面将以下两个方法自动加入到全局事务中。其他方法会调用到原生父类进行,不会加入到全局事务。(原因是request/oneway/批量发送/指定selector的send等很多方法在原生里也不支持事务消息)
方案流程
时序图(正常流程)
一致性问题
参考上面的时序图,考虑以下的正常流程,发现有一致性问题难以解决:
seata分支已产生,但半消息未发送
如果在[3]之前宕机了,消息未发送,seata的分支一阶段也会失败,这种情况下TC有可能发起回滚,但是在事务context里却没有messageid(无法通知mq的broker),这种情况下应该可以直接回滚成功(类似空回滚)
seata分支已产生,半消息已发送,但发送结果和message没有放入context中
如果在[2]之后[3]之前宕机了,TC也会发起回滚,同样的context里也没有messageid,这种情况下有两个问题,
对于问题2,如果拥有回查1阶段状态的能力是可以支持的,但目前现在RM没有这个能力,所以:
会议讨论的结论是TC支持回查,前提是在发送消息时在头部加入xid。
但随之而来的还有一个问题,如果globalstatus查不到呢?这种情况现在看来是回滚或提交已经完成且通知broker了,但broker可能还没收到或者状态还没扭转,又发起了一次回查listener,忽略就可以。
其他问题
支持加入全局事务的producer方法:目前只支持上述两个,其他的暂不考虑。
使用切面还是直接编写SeataMqProducer:直接写SeataMqProducer会更加好读和好维护,虽然在维护上也有其他成本,但是我们现在需要“代理”的方法少,这样做比代理类更加可控,影响范围也更加可控,不会带来额外影响。
Beta Was this translation helpful? Give feedback.
All reactions