shan
2023-09-19
来自河南
RocketMQ事务的实现 1. 生产者发送事务消息 生产者在发送事务消息的时候,会在消息属性中设置PROPERTY_TRANSACTION_PREPARED属性,然后向Broker发送消息,Broker收到消息后,会判断消息是否含有该属性,如果没有该属性,表示是普通消息,按照普通消息处理即可,如果有该属性 表示事务消息,不能直接投递到实际的消息队列中,否则一旦加入就会被消费者消费,所以需要先对消息暂存,RocketMQ设置了一个RMQ_SYS_TRANS_HALF_TOPIC主题先将消息存入这个主题中,此时消息对消费者不可见,不能被消费者消费,称为half消息。 2. half消息发送成功之后,开始执行本地事务(执行executeLocalTransaction方法)。 3. 结束事务,会根据本地事务的执行结果来决定回滚还是提交事务,然后向Broker发送结束事务的请求,请求中携带本地事务的执行结果,Broker收到请求后根据执行结果进行处理: (1)COMMIT_MESSAGE:表示提交事务,请求信息中携带了消息的偏移量,会根据偏移量先查找消息是否存在,如果存在与请求头中携带的消息信息进行对比校验是否一致,校验通过才可以提交事务,然后恢复消息原本的主题和队列,将消息投递到对应的队列中,之后将对应的half消息标记删除; (2)TRANSACTION_ROLLBACK_TYPE:表示回滚事务,同样会先根据请求中的消息偏移量进行查找并校验,通过之后,将对应的half消息进行删除; 由于RocketMQ追加写的性能并不会直接从RMQ_SYS_TRANS_HALF_TOPIC队列中删除消息,而是使用了另外一个主题RMQ_SYS_TRANS_OP_HALF_TOPIC(以下简称OP主题/队列)将已提交或者回滚的事务放入到OP主题的队列中,在补偿机制对half消息进行检查的时候会从此队列中判断是消息是否被删除。 补偿机制(事务状态检查) 在事务处理任一阶段出现异常都有可能导致事务未能成功的进行提交/回滚,所以需要增加一种补偿机制,定时对RMQ_SYS_TRANS_HALF_TOPIC主题中的half消息进行检查。 在处理half消息时,可以通过OP队列来判断消息是否被删除,被删除的消息不需要处理,未被删除的消息,满足回查条件时,可以进行状态回查(执行checkLocalTransaction方法),之后再根据回查结果决定是否需要提交/回滚。
展开