关于引入事务性消息&库存流水方案的必要性的疑问
来源:8-6 库存流水状态(4)

慕数据5069965
2022-10-28
老师好,
我对比了8-1节末尾的方案(我改动了一点)和到现在这节的方案,觉得(在不考虑本地处理线程莫名死掉的情况下,仅考虑异常)后者并没有解决前者的问题:
方案一链路(这里是把mq发送消息放到createOrder最后,不作为aftercommit执行):
app server:redis扣减——订单入库mysql——mq生产者发送消息
mq消费端-mysql:消费消息,mysql减库存
此时会有两个潜在的造成数据不一致的问题:
(1)app server&mq 生产端流程无异常(即返回下单成功),mq消费端失败,此时:redis正确,redis<mysql
(2)app server&mq 生产端流程在redis扣减成功后出现异常(即返回下单失败),此时:mysql正确,redis<mysql
方案二链路:
app server:controller初始化stocklog—— mq生产者预提交事务消息 — mq生产者事务监听器收到事务消息,执行本地事务( redis减库存 — mysql订单入库 ——stocklog修改为成功状态),根据执行情况决定是否发送——controller拿到最终发送决策,返回下单成功/失败
此时会发现上述的两个问题依然存在。
事实上我觉得这里的两阶段提交,mq生产者复查本地事务执行情况,在本地线程不会莫名死掉的情况下是没有必要的,方案一中代码一旦执行到mq生产者发送消息那一步就说明前置操作执行无误,默认决策是发送消息的。
所以这里觉得这个优化好像理论上没有什么提升,麻烦老师看一下我是哪里想错了吗?谢谢啦~
1回答
-
龙虾三少
2022-10-28
我们需要考虑本地线程挂掉 服务重启等各种异常问题 实际生产环境中一秒钟可能就几千单 如果不能正确处理会造成很大的资金和库存问题
01相似问题