订单未支付30分钟自动取消是如何实现的?
本文共 2,398 字,预计阅读时间 8 分钟
很多时候都能看到,当下了订单后10分钟或30分钟未支付,订单会自动取消,具体是如何实现的呢?
本文使用最常用的几种方式,只说明关键的部分,已30分钟为例。
1.借助redis的过期特性
逻辑:
下单时,订单状态是待支付。将订单编号作为key,下单的时间戳作为value,设置过期时间是30分钟。服务器监听redis的key过期事件,如果是订单过期(还会有其他key过期),则修改订单的状态为已取消。当30分钟后未支付则触发redis过期事件,只需修改订单状态即可。若30分钟内支付成功,则需要删除此订单在redis的值。当然,在支付时,需要检查订单是否已超时或已支付。
关键点:
很明确,只需要在应用中添加监听器监听redis过期即可。
首先是配置redis监听器
package com.zxh.example.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.listener.RedisMessageListenerContainer; @Configuration public class RedisListenerConfig { @Bean RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory) { RedisMessageListenerContainer container = new RedisMessageListenerContainer(); container.setConnectionFactory(connectionFactory); return container; } }
继承redis键过期监听器,进行业务处理
package com.zxh.example.config; import com.zxh.example.service.OrderService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.connection.Message; import org.springframework.data.redis.listener.KeyExpirationEventMessageListener; import org.springframework.data.redis.listener.RedisMessageListenerContainer; import org.springframework.stereotype.Component; @Component @Slf4j public class RedisKeyExpirationListener extends KeyExpirationEventMessageListener { @Autowired private OrderService orderService; public RedisKeyExpirationListener(RedisMessageListenerContainer listenerContainer) { super(listenerContainer); } @Override public void onMessage(Message message, byte[] pattern) { // message.toString()可获取失效的key String expiredKey = message.toString(); log.info("------------------redis key 失效; key = {}", expiredKey); if (expiredKey.startsWith("order")) { // 获取订单orderNo String orderNo = expiredKey.substring(expiredKey.lastIndexOf(":") + 1); // 将待支付的订单改为已取消(超时未支付) orderService.orderPaidTimeout(orderNo); } } }
注意:由于存在多个键的过期,故必须对键进行判断,是否是订单超时造成的过期。
2.使用RabbitMQ的过期队列
利用RabbitMQ的过期队列与死信队列,设置消息的存活时间,消息在设置的时间内未被消费,将其投递到死信队列,然后监听死信队列。具体请参考RabbitMQ基本入门 这篇文章
就是这么简单,你学废了吗?感觉有用的话,给笔者点个赞吧 !
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
2021-07-10 SpringBoot邮件发送
2021-07-10 表单中el-select和el-input的长度不一致?