Redis实现订单自动过期功能的示例代码

用户下单后,规定XX分钟后自动设置为“已过期”,不能再发起支付。项目类似此类"过期"的需求,笔者提供一种使用Redis的解决思路,结合Redis的订阅、发布和键空间通知机制(Keyspace Notifications)进行实现。

Posted in Redis onMay 08, 2021

配置redis.confg

notify-keyspace-events选项默认是不启用,改为notify-keyspace-events “Ex”。重启生效,索引位i的库,每当有过期的元素被删除时,向**keyspace@:expired**频道发送通知。
E表示键事件通知,所有通知以__keyevent@__:expired为前缀;
x表示过期事件,每当有过期被删除时发送。

与SpringBoot进行集成

①注册JedisConnectionFactory

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisPassword;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;

import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

@Configuration
public class RedisConfig {
 
 @Value("${redis.pool.maxTotal}")
 private Integer maxTotal;
 
 @Value("${redis.pool.minIdle}")
 private Integer minIdle;
 
 @Value("${redis.pool.maxIdle}")
 private Integer maxIdle;
 
 @Value("${redis.pool.maxWaitMillis}")
 private Integer maxWaitMillis;
 
 @Value("${redis.url}")
 private String redisUrl;
 
 @Value("${redis.port}")
 private Integer redisPort;
 
 @Value("${redis.timeout}")
 private Integer redisTimeout;
 
 @Value("${redis.password}")
 private String redisPassword;
 
 @Value("${redis.db.payment}")
 private Integer paymentDataBase;
 
 private JedisPoolConfig jedisPoolConfig() {
  JedisPoolConfig config = new JedisPoolConfig();
  config.setMaxTotal(maxTotal);
  config.setMinIdle(minIdle);
  config.setMaxIdle(maxIdle);
  config.setMaxWaitMillis(maxWaitMillis);
  return config;
 }
 
 @Bean
 public JedisPool jedisPool() {
  JedisPoolConfig config = this.jedisPoolConfig();
  JedisPool jedisPool = new JedisPool(config, redisUrl, redisPort, redisTimeout, redisPassword);
  return jedisPool;
 }
 
 @Bean(name = "jedisConnectionFactory")
 public JedisConnectionFactory jedisConnectionFactory() {
  RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration();
  redisStandaloneConfiguration.setDatabase(paymentDataBase);
  redisStandaloneConfiguration.setHostName(redisUrl);
  redisStandaloneConfiguration.setPassword(RedisPassword.of(redisPassword));
  redisStandaloneConfiguration.setPort(redisPort);

  return new JedisConnectionFactory(redisStandaloneConfiguration);
 }
}

②注册监听器

import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service(value ="paymentListener")
public class PaymentListener implements MessageListener {

 @Override
 @Transactional
 public void onMessage(Message message, byte[] pattern) {
  // 过期事件处理流程
 }
}

③配置订阅对象

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.listener.PatternTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.listener.adapter.MessageListenerAdapter;

@Configuration
@AutoConfigureAfter(value = RedisConfig.class)
public class PaymentListenerConfig {
 
 @Autowired
 @Qualifier(value = "paymentListener")
 private PaymentListener paymentListener;
 
 @Autowired
 @Qualifier(value = "paymentListener")
 private JedisConnectionFactory connectionFactory;
 
 @Value("${redis.db.payment}")
 private Integer paymentDataBase;
 
 @Bean
 RedisMessageListenerContainer redisMessageListenerContainer(MessageListenerAdapter listenerAdapter) {
        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);
        // 监听paymentDataBase 库的过期事件
        String subscribeChannel = "__keyevent@" + paymentDataBase + "__:expired";
        container.addMessageListener(listenerAdapter, new PatternTopic(subscribeChannel));
        return container;
 }
 
 @Bean
    MessageListenerAdapter listenerAdapter() {
        return new MessageListenerAdapter(paymentListener);
    }
}

paymentDataBase 库元素过期后就会跳入PaymentListener 的onMessage(Message message, byte[] pattern)方法。

到此这篇关于Redis实现订单自动过期功能的示例代码的文章就介绍到这了,更多相关Redis 订单自动过期内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Redis 相关文章推荐
Redis集群的关闭与重启操作
Jul 07 Redis
springboot使用Redis作缓存使用入门教程
Jul 25 Redis
Redis如何实现分布式锁
Aug 23 Redis
为什么RedisCluster设计成16384个槽
Sep 25 Redis
Redis中有序集合的内部实现方式的详细介绍
Mar 16 Redis
Redis 操作多个数据库的配置的方法实现
Mar 23 Redis
Redis如何使用乐观锁(CAS)保证数据一致性
Mar 25 Redis
Redis基本数据类型Zset有序集合常用操作
Jun 01 Redis
关于Redis的主从复制及哨兵问题
Jun 16 Redis
redis lua限流算法实现示例
Jul 15 Redis
基于Redission的分布式锁实战
Aug 14 Redis
redis 限制内存使用大小的实现
使用Redis实现秒杀功能的简单方法
Redis6.0搭建集群Redis-cluster的方法
May 08 #Redis
浅谈Redis存储数据类型及存取值方法
Redis IP地址的绑定的实现
May 08 #Redis
redis通过6379端口无法连接服务器(redis-server.exe闪退)
redis 查看所有的key方式
You might like
php.ini 中文版
2006/10/28 PHP
PHP中cookies使用指南
2007/03/16 PHP
php5.3 注意事项说明
2013/07/01 PHP
ThinkPHP3.1新特性之内容解析输出详解
2014/06/19 PHP
javascript入门·图片对象(无刷新变换图片)\滚动图像
2007/10/01 Javascript
JS的数组的扩展实例代码
2008/07/09 Javascript
jquery创建并行对象或者合并对象的实现代码
2012/10/10 Javascript
js异步加载的三种解决方案
2013/03/04 Javascript
JS远程获取网页源代码实例
2013/09/05 Javascript
导入extjs、jquery 文件时$使用冲突问题解决方法
2014/01/14 Javascript
浅谈JS日期(Date)处理函数
2014/12/07 Javascript
IE10中flexigrid无法显示数据的解决方法
2015/07/26 Javascript
jQuery插件Validate实现自定义校验结果样式
2016/01/18 Javascript
AngularJS基础 ng-readonly 指令简单示例
2016/08/02 Javascript
详解IWinter 一个路由转控制器的 Nodejs 库
2017/11/15 NodeJs
Vue.js项目中管理每个页面的头部标签的两种方法
2018/06/25 Javascript
vue 属性拦截实现双向绑定的实例代码
2018/10/24 Javascript
vue slot与传参实例代码讲解
2019/04/28 Javascript
在JavaScript中实现链式调用的实现
2019/12/24 Javascript
JavaScript中继承原理与用法实例入门
2020/05/09 Javascript
微信小程序实现点击导航标签滚动定位到对应位置
2020/11/19 Javascript
Ubuntu下使用python读取doc和docx文档的内容方法
2018/05/08 Python
Python numpy多维数组实现原理详解
2020/03/10 Python
基于python实现生成指定大小txt文档
2020/07/20 Python
细说NumPy数组的四种乘法的使用
2020/12/18 Python
HTML5 audio标签使用js进行播放控制实例
2015/04/24 HTML / CSS
Helly Hansen工作服美国官方网上商店:为最恶劣的环境
2019/09/04 全球购物
C&A巴西网上商店:时尚、衣服、手机和鞋子
2020/06/07 全球购物
红头文件任命书范本
2014/06/05 职场文书
酒店总经理岗位职责范本
2014/08/08 职场文书
学校法制宣传日活动总结
2014/11/01 职场文书
2014年团委工作总结
2014/11/13 职场文书
数学考试作弊检讨书300字
2015/02/16 职场文书
小学运动会开幕词
2016/03/04 职场文书
Java Lambda表达式常用的函数式接口
2022/04/07 Java/Android
Nginx 502 bad gateway错误解决的九种方案及原因
2022/08/14 Servers