如果你清楚事务是什么,但是对事务消息认知比较模糊,看完这个文章,相信你会有所熟悉。
一、事务消息介绍
二、事务消息整体流程
三、事务消息发送源码
TransactionMQProducer很重要的成员变量,客户端继承实现:
四、事务消息处理源码
prepare消息接口
与正常发送一样,使用SendMessageProcessor接收处理,是Netty的Processor。
本地事务执行状态接收
EndTransactionProcessor内部处理Producer本地事务执行完成发送的消息,状态处理
线程异步回查本地事务状态
回查的前提是Producer端上一步返回了MessageSysFlag.TRANSACTION_NOT_TYPE,或者没有任何状态返回。
异步线程:
TransactionalMessageCheckService,Broker启动时启动。
五、一些QA
消息事务和分布式事务之间的区别是什么?
两者本身没有绝对的关系。
1、消息事务保证的是消息发送和消息发送时的业务逻辑同时失败或者成功。
2、分布式事务保证是分布式中一个需要分布式各节点完成的特定操作,各个节点能够同时失败或者成功,不允许中间状态。
事务消息优缺?
事务消息不保证业务操作的回滚
事务消息是根据业务操作(整体)的成功失败去回滚或者提交消息。
事务消息并不会去care你的业务操作(部分)失败后,是否要去做业务操作(成功部分的)回滚操作。
需要借助外部能力自动去回滚。
事务消息编码不友好
使用事务消息需要开发者实现 TransactionListener 接口。
执行业务操作+查询业务操作是否成功。
前者是正常的业务逻辑,但是还要我们去实现查询业务操作是否成功,这难免有时候会导致情况复杂化。
当然,这不能说MQ做的不对,MQ做事务消息本身的目的就是消息的提交与回滚的事务能力,业务内的数据一致性本不是它考虑的问题。
本地事务和MQ发送原子性的替代方案?
事务增强:拦截本地事务,事务执行成功后,发送MQ。MQ发送失败,业务中重试或者告警。