事务型消息总结

1、事务与分布式事务

事务当中执行操作就是要么全都执行,要么全都不执行。
(1)在单个系统的业务对数据库的普通事务操作,比如转账场景用户A给用户B转账100元。我们先给A扣减100元,再给B增加100元。如果在Spring下,只需给业务逻辑添加封装的数据库层的事务@Transactional注解 即可。
(2)但是在秒杀系统中的扣减库存的应用场景:在redis中扣减库存,异步更新到mysql数据库中去,这就需要保持redis和mysql的数据最终一致性。属于分布式事务范畴。
(单个jvm,数据库分库分表或者多个jvm,服务拆分)
分布式事务解决方案有很多,本篇RocketMQ事务消息仅仅是其中的一种解决方案。

2、秒杀系统的分布式事务方案-执行流程图

在这里插入图片描述
在这里插入图片描述

1、Producer向 MQ 服务端发送消息。
2、MQ Server 将消息持久化成功之后,向发送方 ACK 确认消息已经发送成功,此时消息为半消息。
3、Producer中executeLocalTransaction()方法开始执行本地事务逻辑。
4、Producer根据本地事务执行结果向 MQ Server 提交二次确认(Commit 或是 Rollback),MQ Server 收到 Commit 状态则将半消息标记为可投递,Consumer最终将收到该消息;MQ Server 收到 Rollback 状态则删除半消息,Consumer将不会接受该消息。
在断网或者是应用重启的特殊情况下,上述步骤4提交的二次确认最终未到达 MQ Server,经过固定时间60s后 MQ Server 将对该消息发起消息回查。
5、Producer收到消息回查后,需要检查对应消息的本地事务执行的最终结果。
6、Producer根据检查得到的本地事务的最终状态再次提交二次确认,MQ Server 仍按照步骤4对半消息进行操作。

事务消息发送对应步骤1、2、3、4,事务消息回查对应步骤5、6、7。

3、该方案是保证消息的成功投递。如何解决成功消费问题?

思考:假如这个时候我们消费端失败了怎么办呢?(这个问题后续有讨论,消费失败有2种,第一种是超时了,我们重试即可,第二种是真的处理失败了?该怎么办呢?)

答:在RocketMQ事务消息如何使用的时候我们提到,如果消费失败怎么办?消费失败有2种,第一种是超时了,我们重试即可,第二种是真的处理失败了?仔细思考下,这块还是蛮复杂的,假如需要有7-8个业务模块呢,其中执行到第6个业务模块就失败呢? 这种重试好几次还是失败,我们该如何处理呢???是回滚前面5个操作吗?好复杂好复杂,为什么RocketMQ不提供自动回滚呢?

某位阿里员工给出一种说法:一般RocketMq会有消息重试机制,如果反复重试失败,需要将消息记录日志,人工分析日志以解决该问题。但是反复重试失败的概率非常小。所以一般不会给出特定的解决方案。

参考:

1、https://blog.csdn.net/lirenzuo/article/details/81275785
2、http://rocketmq.apache.org/rocketmq/the-design-of-transactional-message/

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值