当前位置: 首页 > news >正文

利用redis实现订单倒计结束后更改订单状态为已失效

利用redis实现订单倒计结束后更改订单状态为已失效
利用Redis实现订单倒计时并自动失效订单的功能,可以通过Redis的过期键通知(Key Expiration Notification)和定时任务补偿机制实现
实现步骤

  1. 配置Redis启用过期事件
    修改Redis配置文件 redis.conf,开启键过期事件通知:

启用过期事件通知

notify-keyspace-events Ex

并且启用Redis的持久化
save 900 1
save 300 10
save 60 10000

重启Redis服务使配置生效。

  1. Java监听Redis过期事件
    使用Spring Data Redis或Jedis监听键过期事件。
    示例代码(Spring Data Redis):
package com.transport.framework.config;import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
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.PatternTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;/*** redis配置* * @author transport*/
@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {@Beanpublic RedisMessageListenerContainer redisMessageListenerContainer(RedisConnectionFactory connectionFactory,OrderExpirationListener orderExpirationListener) {RedisMessageListenerContainer container = new RedisMessageListenerContainer();container.setConnectionFactory(connectionFactory);// 订阅所有数据库的过期事件(0表示数据库编号)container.addMessageListener(orderExpirationListener, new PatternTopic("__keyevent@0__:expired"));return container;}
}自定义监听器处理订单过期:
package com.transport.framework.config;import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.stereotype.Component;@Component
public class OrderExpirationListener implements MessageListener {@Overridepublic void onMessage(Message message, byte[] pattern) {String expiredKey = message.toString();// 解析订单ID(假设key格式为order:订单ID)if (expiredKey.startsWith("order:")) {String orderNo = expiredKey.split(":")[1];// 调用订单服务更新订单状态为失效System.out.println("已失效的订单编号为:"+orderNo);}}
}
订单服务更新状态:
代码省略(注意:只有未支付的订单才更新状态)
3. 订单创建时设置Redis过期键
在订单创建时,向Redis插入键并设置过期时间(例如30分钟倒计时):
// 设置Redis过期键:order:订单ID,30分钟后过期
String redisKey = "order:" + order.getId();
redisTemplate.opsForValue().set(redisKey, "1", Duration.ofMinutes(30));
4. 兜底方案:定时任务补偿
为防止Redis事件丢失,增加定时任务扫描数据库中未过期的订单:
@Scheduled(cron = "0 */5 * * * ?") // 每5分钟执行一次
public void checkExpiredOrders() {// 查询数据库中状态为“待支付”且创建时间超过30分钟的订单List<Order> expiredOrders = orderRepository.findExpiredOrders(OrderStatus.PENDING, LocalDateTime.now().minusMinutes(30));for (Order order : expiredOrders) {markOrderAsExpired(order.getId());// 可选:删除Redis中的键(避免重复处理)redisTemplate.delete("order:" + order.getId());}
}

相关文章:

  • 大数据调度组件
  • 怎么用面向对象和状态机架构,设计一个通用的按键检测功能?
  • 【docker】运行错误提示 unknown shorthand flag: ‘d‘ in -d ----详细解决方法
  • 2025 全球分布式云大会演讲实录 | 沈建发:智启边缘,畅想未来:边缘计算新场景落地与 Al 趋势新畅想
  • 探秘Transformer系列之(28)--- DeepSeek MLA(下)
  • 卷积神经网络CNN(李宏毅)
  • 【android telecom 框架分析 01】【基本介绍 2】【BluetoothPhoneService为何没有源码实现】
  • Java八种常见的设计模式
  • MySQL GTID集合运算函数总结
  • 33、Python单元测试与pytest框架从入门到精通
  • MQTT客户端核心源码解析:从发布机制到网络循环
  • [图论]Kruskal
  • Golang errors 包快速上手
  • 【安卓开发】【Android Studio】Menu(菜单栏)的使用及常见问题
  • Python解决“小D的abc字符变换”问题
  • 手机状态:UML 状态图(State Diagram)的解析与绘画
  • 天洑参加人工智能校企产学研及人才对接活动——走进南京大学人工智能学院
  • NO.96十六届蓝桥杯备战|图论基础-多源最短路|Floyd|Clear And Present Danger|灾后重建|无向图的最小环问题(C++)
  • Opencv函数及练习题
  • C# 如何比较两个List是否相等?
  • 没有握手,采用翻译:俄乌三年来首次直接会谈成效如何?
  • 国家防汛抗旱总指挥部对15个重点省份开展汛前实地督导检查
  • 时隔三年,俄乌直接谈判重启
  • 张家界一铁路致17人身亡,又有15岁女孩殒命,已开始加装护栏
  • 上海老字号卖黄金,与动漫IP联名两周销售额近亿元
  • 通往国际舞台之路:清政府与万国公会的交往