订单超时取消的实现,首先想到的是定时任务,但是这种实现方式在订单量较大的情况下是有问题的,而且时间也会有误差,最大时间差就是定时任务的执行间隔时间。
使用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秒后程序成功监听到了过期事件:
到此这篇关于基于Redis过期事件实现订单超时取消的文章就介绍到这了,更多相关Redis 订单超时取消内容请搜索自学编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持自学编程网!
- 本文固定链接: https://zxbcw.cn/post/211679/
- 转载请注明:必须在正文中标注并保留原文链接
- QQ群: PHP高手阵营官方总群(344148542)
- QQ群: Yii2.0开发(304864863)