订单超时取消的实现,首先想到的是定时任务,但是这种实现方式在订单量较大的情况下是有问题的,而且时间也会有误差,最大时间差就是定时任务的执行间隔时间。
使用redis的过期监听事件可以比较好的解决这个问题。实现的方式是订单创建后向redus中存一记录,一般就以订单号为key。设置过期时间(订单超时时间),一旦时间超时会触发监听事件,这时候就可以通过key判断这个订单是否支付,未支付时取消订单。
redis过期监听的实现:
1.修改redis.windows.conf配置文件中notify-keyspace-events的值
默认配置notify-keyspace-events的值为" ",修改为 notify-keyspace-events Ex 这样便开启了过期事件
2. 创建配置类RedisListenerConfig(配置RedisMessageListenerContainer这个Bean)
@Configuration public class RedisListenerConfig { @Autowired private RedisTemplate redisTemplate; /** * 处理乱码 * @return */ @Bean public RedisTemplate redisTemplateInit() { // key序列化 redisTemplate.setKeySerializer(new StringRedisSerializer()); //val实例化 redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer()); return redisTemplate; } @Bean RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory) { RedisMessageListenerContainer container = new RedisMessageListenerContainer(); container.setConnectionFactory(connectionFactory); return container; } }
3.继承KeyExpirationEventMessageListener创建redis过期事件的监听类
KeyExpirationEventMessageListener类是org.springframework.data.redis.listener包下的实现类,通过继承这个类重写onMessage方法可以实现对redis所有过期事件的监听。
@Component public class RedisKeyExpirationListener extends KeyExpirationEventMessageListener { public RedisKeyExpirationListener(RedisMessageListenerContainer container) { super(container); } /** * 针对redis数据失效事件,进行数据处理 * @param message * @param pattern */ @Override public void onMessage(Message message, byte[] pattern) { String key=message.toString();//生效的key if (key!=null && key.startsWith("order")){//从失效key中筛选代表订单失效的key //截取订单号,查询订单,如果是未支付状态则取消订单 String orderNo=key.substring(5); System.out.println("订单号为:"+orderNo+"的订单超时未支付,取消订单"); } } }
测试
通过redis模拟创建一个有效时间为5s的订单:
5秒后程序成功监听到了过期事件:
转载:https://www.jb51.net/article/211679.htm
分类:
JAVA
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· .NET Core 中如何实现缓存的预热?
· 三行代码完成国际化适配,妙~啊~
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?