如果对你有用点个赞吧
需求
处理订单下单后30分钟未付款自动取消
解决方案
利用redis中key自动过期机制,提交订单时将订单编号写入redis,并设置30分钟的过期时间,当订单过期后,取到过期的key然后做业务处理。
功能开发
- 开启redis过期提醒
本次使用window版本redis。修改redis.windows.conf 中892行中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”意味着所有事件。
- 修改完成后请重启redis服务,打开redis-cli
B:\Program Files (x86)\Redis-x64-3.2.100>redis-cli
127.0.0.1:6379> psubscribe __keyevent@0__:expired
Reading messages... (press Ctrl-C to quit)
1) "psubscribe"
2) "__keyevent@0__:expired"
3) (integer) 1
再开启一个客户端放置一个测试的过期数据
B:\Program Files (x86)\Redis-x64-3.2.100>redis-cli
set Order:123 123 PX 100
第一个客户端能够收到消息
1) "pmessage"
2) "__keyevent@0__:expired"
3) "__keyevent@0__:expired"
4) "Order:123"
设置redis配置
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;
/**
* @Author linyuchi
* @Date 2018/10/27 20:56
*/
@Configuration
public class RedisListenerConfig {
@Bean
RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory) {
RedisMessageListenerContainer container = new RedisMessageListenerContainer();
container.setConnectionFactory(connectionFactory);
return container;
}
}
import com.plusesb.constant.ShSysConstant;
import com.plusesb.service.ShOrderService;
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;
/**
* 监听所有db的过期事件__keyevent@*__:expired"
* @author linyuchi
*/
@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);
}
}
}
这样就实现了订单自动取消的功能。同理可以使用到发货后14天后自动确认到货。
网友评论