1 引言
RocketMQ的事务消息设计是为了解决分布式系统中数据一致性的问题。在分布式系统中,由于数据可能分布在不同的服务或节点上,因此需要一种机制来确保数据的最终一致性。事务消息通过引入本地事务和消息状态的关联,确保了消息的发送与本地事务的执行结果紧密相关,从而避免了数据不一致的问题。
2 事务消息步骤
- 生产者将半事务消息发送至 RocketMQ Broker。
- RocketMQ Broker 将消息持久化成功之后,向生产者返回 Ack 确认消息已经发送成功,此时消息暂不能投递,为半事务消息。
- 生产者开始执行本地事务逻辑。
- 生产者根据本地事务执行结果向服务端提交二次确认结果(Commit或是Rollback),服务端收到确认结果后处理逻辑如下:
4.1 二次确认结果为Commit:服务端将半事务消息标记为可投递,并投递给消费者。
4.2 二次确认结果为Rollback:服务端将回滚事务,不会将半事务消息投递给消费者。 - 在断网或者是生产者应用重启的特殊情况下,若服务端未收到发送者提交的二次确认结果,或服务端收到的二次确认结果为Unknown未知状态,经过固定时间后,服务端将对消息生产者即生产者集群中任一生产者实例发起消息回查。
5.1 生产者收到消息回查后,需要检查对应消息的本地事务执行的最终结果。
5.2 生产者根据检查得到的本地事务的最终状态再次提交二次确认,服务端仍按照步骤4对半事务消息进行处理。 - 注意:服务端仅仅会按照参数尝试指定次数,超过次数后事务会强制回滚,因此未决事务的回查时效性非常关键,需要按照业务的实际风险来设置。
3 项目结构
本章内容以Spring Cloud Alibaba 快速学习之 RocketMQ中的项目为基础稍作修改。下面列出修改的文件。
3.1 项目rocketmq-producer
- application.properties
这里添加了事务相关的配置
#spring应用程序监听的端口号
server.port=8080
#spring应用程序的名称
spring.application.name=rocketmq-producer
#spring当前激活的配置文件
spring.profiles.active=dev
#rocketmq 服务地址
spring.cloud.stream.rocketmq.binder.name-se