方案
- 事务消息投递的过程
- step1:开启本地事务
- step2:执行本地业务
- step3:消息表t_msg写入记录,status为0(待投递到MQ)
- step4:提交本地事务
- step5:若事务提交成功,则投递消息到MQ,然后将t_msg中的status置为1(投递成功);本地事务失败的情况不用考虑,此时消息记录也没有写到db中
- 异常情况
step5失败了,其他步骤都成功,此时业务执行成功,但是消息投递失败了,此时需要有个job来进行补偿,对于投递失败的消息进行重试。
- 消息投递补偿job
这个job负责从本地t_msg表中查询出状态为0记录或者失败需要重试的记录,然后进行重新投递到MQ。
对于投递失败的,采用衰减的方式进行重试,比如第1次失败了,则10秒后,继续重试,若还是失败,则再过20秒,再次重试,需要设置一个最大重试次数,最终还是投递失败,则需要告警+人工干预。
代码实现
事务消息投递的过程
异常情况的处理
当事务提交成功,但是消息投递过程中出现异常投递失败时,采用一个Job每20秒执行一次,查出所有投递失败的消息,重新投递。