✅什么是事务消息,为什么需要事务消息?
典型回答
如果不用事务消息,就用本地消息的话,那么一次操作一般是这样的流程:
1、执行本地事务
2、发送MQ消息
3、消费MQ消息

如果一切顺利,那么没啥说的,双方都能处理成功,最终是一致的,但是实际情况是,因为网络延迟、网络抖动、服务器本身的稳定性、MQ自身的稳定性等原因,这个过程会出现各种各样的问题。
一旦在第一个参与者本地事务操作之后,如果出现了MQ发送失败、或者发送成功了,但是MQ自己存储失败了等原因,可能就会导致不一致了。
有人会问了,那这里如果MQ发失败了,本地事务回滚不就行了么?
有问题,因为会出现一种极端情况,那就是当出现网络抖动的时候,发送MQ因为网络超时返回了失败,本地事务回滚之后,但是网络超时不一定是MQ没有接收到,有可能处理成功了,但是返回的时候超时了。这时候就会出现:本地事务回滚了、但是MQ发送成功了的问题。这时候下游正常消费MQ之后,就又出现不一致了。
而且,MQ自身也不一定可靠,不管是哪种MQ,在极端情况下,都是有可能丢消息的,也就说,可能会出现本地事务成功之后,发送MQ成功了,但是因为MQ自身原因,导致消息丢了,还是会出现不一致。
所以,总之就是引入MQ之后,会因为各种原因导致不一致,那怎么解决这个问题呢?
解决方案就是能有一个机制保证MQ一定可以发送成功,或者是如果失败了,也有机制能够重试让他成功。
那么这个方案就是事务消息(RocketMQ中的那种,非Kafka中的那种),即把一个发送消息的过程拆成2步,先发一个半消息,确保成功之后,在执行本地事务,本地事务成功后,再发第二个半消息。

如果第一个半消息发失败了,本地事务不会执行。
如果第一个半消息发成功了,本地事务执行失败了,MQ也不会消费。
如果第二个半消息发送失败了,MQ会反查来决定commit还是rollback。
具体参考: