一、整体流程回顾
- 前端下单请求进来,先查 Redis 库存
- 执行
DECR原子扣减:- 结果 < 0 → 库存不足,直接返回失败
- 结果 ≥ 0 → 扣减成功,发送消息到 MQ
- MQ 消费者消费消息,异步更新数据库库存
- 配套:消息重试、定时对账、DB 乐观锁防重复扣减
二、核心依赖(pom.xml 关键)
<!-- Spring Data Redis --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <!-- RabbitMQ --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-amqp</artifactId> </dependency> <!-- MyBatis/MyBatis-Plus 操作DB --> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency>三、常量 & MQ 队列配置
1. 常量类
public class StockConstant { // Redis 库存 key 前缀 public static final String REDIS_STOCK_PREFIX = "product:stock:"; // MQ 队列名称 public static final String STOCK_SYNC_QUEUE = "stock.sync.queue"; }2. RabbitMQ 配置(队列、交换机、绑定)
import org.springframework.amqp.core.Queue; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class RabbitConfig { @Bean public Queue stockSyncQueue() { // 持久化队列,宕机不丢失消息 return new Queue(StockConstant.STOCK_SYNC_QUEUE, true); } }四、库存实体 & Mapper(DB 层)
1. 商品库存实体(带乐观锁)
import com.baomidou.mybatisplus.annotation.Version; import lombok.Data; @Data public class ProductStock { private Long id; // 商品ID private Long productId; // 数据库真实库存 private Integer stock; // 乐观锁版本号,防止异步重复扣减 @Version private Integer version; }