需求
處理訂單下單后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); } } }