关于引入事务性消息&库存流水方案的必要性的疑问

来源: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

我们需要考虑本地线程挂掉 服务重启等各种异常问题 实际生产环境中一秒钟可能就几千单 如果不能正确处理会造成很大的资金和库存问题

0
1
慕数据5069965
即便是考虑本地线程挂掉的问题,我们根据挂掉的代码执行位置分为: redis扣减库存前:方案一前端收到下单失败,不影响数据一致;方案二前端收到下单失败,恢复后stocklog状态为1(unknown),得知本地事务执行中断,mq不发送,不影响数据一致。二者效果一致。 reids扣减库存后:方案一前端收到下单失败,订单若落库会造成无效的订单,mq作为最后一步一定未发送成功。此时mysql数据正确,redis
2022-10-28
共1条回复

聚焦Java性能优化 打造亿级流量秒杀系统(赠秒杀项目)

理解高流量电商网站性能构建思路 用高逼格技术解决性能提升问题

2170 学习 · 1009 问题

查看课程