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 相关文章推荐
为Java项目添加Redis缓存的方法
May 18 Redis
详解Redis主从复制实践
May 19 Redis
Redis中一个String类型引发的惨案
Jul 25 Redis
Redis入门教程详解
Aug 30 Redis
基于Redis的List实现特价商品列表功能
Aug 30 Redis
Redis字典实现、Hash键冲突及渐进式rehash详解
Sep 04 Redis
linux下安装redis图文详细步骤
Dec 04 Redis
redis数据结构之压缩列表
Mar 21 Redis
Redis分布式锁的7种实现
Apr 01 Redis
Redis高并发缓存架构性能优化
May 15 Redis
Redis特殊数据类型HyperLogLog基数统计算法讲解
Jun 01 Redis
Redis全局ID生成器的实现
Jun 05 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内核之php in array
2015/11/10 PHP
远离JS灾难css灾难之 js私有函数和css选择器作为容器
2011/12/11 Javascript
IE的有条件注释判定IE版本详解(附实例代码)
2012/01/04 Javascript
ActiveX控件与Javascript之间的交互示例
2014/06/04 Javascript
JavaScript实现跨浏览器的添加及删除事件绑定函数实例
2015/08/04 Javascript
Angular.js 实现数字转换汉字实例代码
2016/07/14 Javascript
Javascript字符串常用方法详解
2016/07/21 Javascript
完美解决jQuery符号$与其他javascript 库、框架冲突的问题
2016/08/09 Javascript
AngularJS表单详解及示例代码
2016/08/17 Javascript
JavaScript获取URL中参数querystring的方法详解
2016/10/11 Javascript
JavaScript实现父子dom同时绑定两个点击事件,一个用捕获,一个用冒泡时执行顺序的方法
2017/03/30 Javascript
基于bootstrap实现多个下拉框同时搜索功能
2017/07/19 Javascript
基于JavaScript实现数码时钟效果
2020/03/30 Javascript
浅谈vue同一页面中拥有两个表单时,的验证问题
2018/09/18 Javascript
elementUi vue el-radio 监听选中变化的实例代码
2019/06/28 Javascript
使用vuex较为优雅的实现一个购物车功能的示例代码
2019/12/09 Javascript
Vue 3.0 全家桶抢先体验
2020/04/28 Javascript
在项目vue中使用echarts的操作步骤
2020/09/07 Javascript
详细解读Python中的__init__()方法
2015/05/02 Python
Python运算符重载用法实例
2015/05/28 Python
深入解析Python编程中super关键字的用法
2016/06/24 Python
Python之列表的插入&替换修改方法
2018/06/28 Python
Python OpenCV 使用滑动条来调整函数参数的方法
2019/07/08 Python
Python使用Tkinter实现滚动抽奖器效果
2020/01/06 Python
详解基于python的图像Gabor变换及特征提取
2020/10/26 Python
python中温度单位转换的实例方法
2020/12/27 Python
Python 中的函数装饰器和闭包详解
2021/02/06 Python
什么是触发器(trigger)? 触发器有什么作用?
2013/09/18 面试题
网站设计师的岗位职责
2013/11/21 职场文书
幼儿园园长岗位职责
2013/11/26 职场文书
申请任职学生会干部自荐书范文
2014/02/13 职场文书
安全责任书范本
2014/04/15 职场文书
以幸福为主题的活动方案
2014/08/22 职场文书
学习计划书怎么写
2014/09/15 职场文书
民事二审代理词
2015/05/25 职场文书
Spring依赖注入多种类型数据的示例代码
2022/03/31 Java/Android