需求
处理订单下单后30分钟未付款自动取消
解决方案
利用redis中key自动过期机制,提交订单时将订单编号写入redis,并设置30分钟的过期时间,当订单过期后,取到过期的key然后做业务处理。
功能开发
1、开启redis过期提醒
本次使用lunix版本redis。修改redis.conf 中1061行中【notify-keyspace-events ""】修改为【notify-keyspace-events Ex】
相关配置参数说明
K:keyspace事件,事件以__keyspace@<db>__为前缀进行发布; E:keyevent事件,事件以__keyevent@<db>__为前缀进行发布; g:一般性的,非特定类型的命令,比如del,expire,rename等; $:字符串特定命令; l:列表特定命令; s:集合特定命令; h:哈希特定命令; z:有序集合特定命令; x:过期事件,当某个键过期并删除时会产生该事件; e:驱逐事件,当某个键因maxmemore策略而被删除时,产生该事件; A:g$lshzxe的别名,因此”AKE”意味着所有事件。
2、重启redis服务
3、代码中设置redis配置
@Configuration public class RedisListenerConfig { @Bean RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory) { RedisMessageListenerContainer container = new RedisMessageListenerContainer(); container.setConnectionFactory(connectionFactory); return container; } }
/** * 监听所有db的过期事件__keyevent@*__:expired" */ @Component @Slf4j public class RedisKeyExpirationListener extends KeyExpirationEventMessageListener { public RedisKeyExpirationListener(RedisMessageListenerContainer listenerContainer) { super(listenerContainer); } @Autowired ShOrderService shOrderService; /** * 针对redis数据失效事件,进行数据处理 * @param message * @param pattern */ @Override public void onMessage(Message message, byte[] pattern) { // 用户做自己的业务处理即可,注意message.toString()可以获取失效的key String expiredKey = message.toString(); log.info("======================redis time out========================"); if(expiredKey.startsWith(ShSysConstant.ORDER_PENDING)){ // 取到业务数据进行处理 String orderNumber = expiredKey.substring(6); log.info("======================"+orderNumber+"======================"); shOrderService.cancelOrderByRedis(orderNumber); } } }