首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >商城交易事务一致性保障方案

商城交易事务一致性保障方案

原创
作者头像
不做虫子
发布2025-11-04 22:59:27
发布2025-11-04 22:59:27
60
举报
文章被收录于专栏:软件系统思考软件系统思考

背景

一手交钱,一手交货

商城业务算是逻辑最严谨的业务之一,钱可千万不能算错。算少了,容易被薅羊毛,算多了,容易遭遇大规模投诉。

其中两个概念非常重要:

  • 原子性:多个操作必须合并成一个原子操作,即事务。
  • 能量守恒:入账出账的值必须一样

设计原则

  • 能单机事务就单机事务,别搞分布式事务,复杂度直线上升;
  • 实在不行要做分布式事务,逻辑要尽可能简单无脑;
  • 可用性达到百分之一百是做梦,最后需要有兜底逻辑,最后的最后是人工兜底;

业界一般采用的方案有“

整体设计

主要模块有:

  • 交易服务:主逻辑代码
  • 金币钱包:业务性质的货币
  • 库存系统:管理库存
  • 订单管理:管理订单的状态
  • 对账系统:负责账目的正确性

详细设计

下单--->支付--->交货

主要的模块包括

  • 下单模块:生成订单和预处理库存;
  • 支付模块:生成支付订单、接收第三方支付结果通知;
  • 对账模块:订单和库存数据定时对账;
  • 异常处理:处理异常情况和异常告警,对失败的事务进行兜底;

下单

下单这里的主要问题是要保证**生成订单**和**减库存**是原子性的操作,不能出现一方成功一方失败。

那么,如何实现呢?

方案:加入异常消息队列,交易模块

下图就是加入异常队列后有异常时的操作流程。

支付模块

交易模块主要问题是保证扣钱和发货的事务性,扣钱了必须要要发货。

扣钱这里也可能涉及到多个币种,例如微信读书的限时书币和永久书币,肯定是先扣了限时书币再扣除永久书币,或者书币扣完了再扣钱,其中一方失败都需要回滚或重试。

这里以书币为例,先扣书币再拉起支付扣钱。

这里我们可以先冻结掉书币,是冻结不是真扣,真扣除就会有流水。

再拉起支付,等待支付结果的状态回调,从而顺利进行下一步流程。

对账模块

对账模块主要是以订单为维度,扫描各个订单的处理流程是否正常。

是否扣库存失败、是否支付失败、是否发货失败等等

这就要求:

  • 交易过程中每一步都要先写流水后进行操作,先操作后流水的弊端是万一存流水失败,那这笔交易就不见了,不好追查。有了流水对账模块才能更好追踪状态。
  • 实时对账各个系统各个订单的状态,各个模块提供对外的状态接口

最后

所有自动化流程都可能失败,最终依赖异常处理模块(自动告警+重试)和人工介入——比如对账发现“扣了钱没发货”,系统自动触发补发,仍失败则通知运营/开发手动处理。

并不是说百分比自动补偿做不到,而是性价比太差,最后由人工兜底是比较划算的。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 背景
  • 设计原则
  • 整体设计
  • 详细设计
    • 下单
    • 支付模块
    • 对账模块
  • 最后
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档