订单 30 分钟过期 + 临界支付 完整 Java 代码实战讲解
目录先定义核心场景一、核心实体与常量二、核心工具:Redis 分布式锁(解决并发竞态)三、场景 1:订单自动过期任务(30 分钟触发)代码逻辑(关键)四、场景 2:用户支付接口(临界时刻核心处理)代码逻辑(最关键)五、场景 3:支付回调兜底(防止极端资损)六、临界时刻(无限接近 30 分钟)代码执行结果情况 1:支付请求先抢到锁情况 2:过期任务先抢到锁七、生产级优化:时间缓冲区(从源头避免临界)八、代码核心总结(面试 + 实战通用)本文用SpringBoot + Redis 分布式锁 + 延迟队列 (模拟) + 支付回调完整复现生产级代码,专门解决无限接近 30 分钟时支付的竞态问题。先定义核心场景订单创建时间:createTime订单过期时间:expireTime = createTime + 30分钟临界问题:支付请求和过期取消任务同时触发目标:绝对不允许:钱扣了,订单却取消;也不允许:订单取消了,还能支付成功一、核心实体与常量import lombok.Data; import java.time.LocalDateTime; // 订单实体 @Data public class Order { private String orderNo; // 订单号 private Integer status; // 0-待支付 1-已支付 2-已取消 private LocalDateTime createTime; private LocalDateTime expireTime; // 过期时间=创建+30分钟 } // 订单状态常量 interface OrderStatus { int WAIT_PAY = 0; // 待支付 int PAID = 1; // 已支付 int CANCELED = 2; // 已取消 }二、核心工具:Redis 分布式锁(解决并发竞态)作用:同一订单,支付和过期任务只能有一个先执行,从根本上杜绝冲突。 我们用Redisson(生产标准方案):@Resource private RedissonClient redissonClient; // 获取订单锁:锁key=订单号,锁超时10秒(防止死锁) private RLock getOrderLock(String orderNo) { return redissonClient.getLock("ORDER_LOCK:" + orderNo); }三、场景 1:订单自动过期任务(30 分钟触发)代码逻辑(关键)加分布式锁,只允许一个实例执行二次校验:订单是否还是待支付 + 是否真的到过期时间满足条件 → 改为已取消/** * 订单过期取消任务(延迟队列30分钟后执行) */ public void orderExpireCancel(String orderNo) { RLock lock = getOrderLoc