首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >MySQL+RabbitMQ死信队列完整解决支付库存方案

MySQL+RabbitMQ死信队列完整解决支付库存方案

原创
作者头像
猿来是后端
发布2025-07-03 16:33:25
发布2025-07-03 16:33:25
1150
举报

1. 用户下单阶段

1.1 前端提交订单数据

  • 商品ID:123
  • 购买数量:1
  • 收货地址:北京市朝阳区

1.2 后端接收参数验证

代码语言:java
复制
if(productId == null || quantity <= 0){

  throw new IllegalArgumentException("参数错误");

}

2. 库存扣减(MySQL事务)

2.1 开启数据库事务

代码语言:sql
复制
START TRANSACTION;

2.2 锁定并检查库存

代码语言:sql
复制
SELECT stock FROM products WHERE id=123 FOR UPDATE;

-- 返回:当前库存10件

2.3 执行库存扣减

代码语言:sql
复制
UPDATE products SET stock=stock-1 WHERE id=123 AND stock>=1;

-- 影响行数:1(成功)

3. 创建订单记录

3.1 生成订单编号

代码语言:java
复制
String orderNo = "O" + System.currentTimeMillis();

3.2 插入订单数据

代码语言:sql
复制
INSERT INTO orders 

(order\_no,user\_id,status,total\_amount)

VALUES 

('O168123456',1001,'待支付',299.00);

3.3 提交事务

代码语言:sql
复制
COMMIT;

4. 发送支付消息队列

4.1 构建消息内容

代码语言:json
复制
{

  "orderNo": "O168123456",

  "amount": 299,

  "userId": 1001

}

4.2 设置消息过期时间

代码语言:java
复制
// 设置30分钟过期

message.getMessageProperties().setExpiration("1800000"); 

4.3 发送到RabbitMQ

代码语言:java
复制
rabbitTemplate.send("order.pay.exchange", "pay.routing.key", message);

5. 支付消息处理

5.1 消费者接收消息

代码语言:java
复制
@RabbitListener( queues = "queue.order.pay")

public void process(OrderMessage message){

  // 处理逻辑...

}

5.2 调用微信支付接口

代码语言:java
复制
WXPayResponse response = wxPay.unifiedOrder(

  message.getOrderNo(),

  message.getAmount()

);

5.3 更新订单状态

代码语言:sql
复制
UPDATE orders SET status='已支付' 

WHERE order\_no='O168123456' AND status='待支付';

6. 死信队列处理(超时未支付)

6.1 消息超时条件

  • 消息在队列中超过30分钟未被消费
  • 消费者处理失败(抛异常)

6.2 死信队列消费者

代码语言:java
复制
@RabbitListener: queues = "dlq.order.cancel")

public void handleTimeoutOrder(OrderMessage message){

  // 回滚库存...

}

6.3 库存回滚操作

代码语言:sql
复制
UPDATE products SET stock=stock+1 WHERE id=123;

6.4 订单状态更新

代码语言:sql
复制
UPDATE orders SET status='已取消' 

WHERE order\_no='O168123456' AND status='待支付';

7. 补偿机制(双保险)

7.1 数据库标记字段

代码语言:sql
复制
ALTER TABLE orders ADD COLUMN mq\_processed TINYINT DEFAULT 0;

7.2 定时任务检查

代码语言:sql
复制
-- 每小时执行的SQL

UPDATE orders SET status='已取消'

WHERE status='待支付'

AND create\_time < NOW() - INTERVAL 30 MINUTE

AND mq\_processed=0;

完整流程图示

代码语言:txt
复制
graph LR

    A[用户下单] --> B[MySQL扣库存]

    B --> C[创建订单]

    C --> D[发支付消息]

    D --> E[正常支付处理]

    E --> F[更新为已支付]

    D -->|30分钟超时| G[死信队列]

    G --> H[回滚库存]

    G --> I[标记已取消]

    H --> J[定时任务兜底]

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

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

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 用户下单阶段
    • 1.1 前端提交订单数据
    • 1.2 后端接收参数验证
  • 2. 库存扣减(MySQL事务)
    • 2.1 开启数据库事务
    • 2.2 锁定并检查库存
    • 2.3 执行库存扣减
  • 3. 创建订单记录
    • 3.1 生成订单编号
    • 3.2 插入订单数据
    • 3.3 提交事务
  • 4. 发送支付消息队列
    • 4.1 构建消息内容
    • 4.2 设置消息过期时间
    • 4.3 发送到RabbitMQ
  • 5. 支付消息处理
    • 5.1 消费者接收消息
    • 5.2 调用微信支付接口
    • 5.3 更新订单状态
  • 6. 死信队列处理(超时未支付)
    • 6.1 消息超时条件
    • 6.2 死信队列消费者
    • 6.3 库存回滚操作
    • 6.4 订单状态更新
  • 7. 补偿机制(双保险)
    • 7.1 数据库标记字段
    • 7.2 定时任务检查
  • 完整流程图示
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档