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主从复制实践
May 19 Redis
Redis基于Bitmap实现用户签到功能
Jun 20 Redis
redis requires ruby version2.2.2的解决方案
Jul 15 Redis
Redis Stream类型的使用详解
Nov 11 Redis
分布式Redis Cluster集群搭建与Redis基本用法
Feb 24 Redis
redis击穿 雪崩 穿透超详细解决方案梳理
Mar 17 Redis
Redis高并发缓存架构性能优化
May 15 Redis
Redis特殊数据类型HyperLogLog基数统计算法讲解
Jun 01 Redis
Redis基本数据类型哈希Hash常用操作命令
Jun 01 Redis
Redis基本数据类型List常用操作命令
Jun 01 Redis
Redis实现主从复制方式(Master&Slave)
Jun 21 Redis
Redis sentinel哨兵集群的实现步骤
Jul 15 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 PDOStatement::getAttribute讲解
2019/02/01 PHP
php日志函数error_log用法实例分析
2019/09/23 PHP
ajax 文件上传应用简单实现
2009/03/03 Javascript
javascript 解决表单仍然提交即使监听处理函数返回false
2010/03/14 Javascript
jQuery 网易相册鼠标移动显示隐藏效果实现代码
2013/03/31 Javascript
js获取时间(本周、本季度、本月..)
2013/11/22 Javascript
javascript实现存储hmtl字符串示例
2014/04/25 Javascript
jQuery实现鼠标经过提示信息的地图热点效果
2015/04/26 Javascript
jQuery原型属性和原型方法详解
2015/07/07 Javascript
jquery中的工具使用方法$.isFunction, $.isArray(), $.isWindow()
2015/08/09 Javascript
JS获取本周周一,周末及获取任意时间的周一周末功能示例
2017/02/09 Javascript
详解在vue-cli项目中使用mockjs(请求数据删除数据)
2017/10/23 Javascript
Vue微信项目按需授权登录策略实践思路详解
2018/05/07 Javascript
vue使用better-scroll实现下拉刷新、上拉加载
2018/11/23 Javascript
[01:50]2014DOTA2西雅图邀请赛 专访欢乐周宝龙
2014/07/08 DOTA
[42:24]完美世界DOTA2联赛循环赛 LBZS vs DM BO2第一场 11.01
2020/11/02 DOTA
Python 实现购物商城,含有用户入口和商家入口的示例
2017/09/15 Python
Python基于更相减损术实现求解最大公约数的方法
2018/04/04 Python
python3中函数参数的四种简单用法
2018/07/09 Python
python实现简单名片管理系统
2018/11/30 Python
python 实现交换两个列表元素的位置示例
2019/06/26 Python
Python 转换文本编码实现解析
2019/08/27 Python
你应该知道的Python3.6、3.7、3.8新特性小结
2020/05/12 Python
keras绘制acc和loss曲线图实例
2020/06/15 Python
Pytorch之扩充tensor的操作
2021/03/04 Python
一款利用html5和css3实现的3D滚动特效的教程
2015/01/04 HTML / CSS
基于html和CSS3制作酷炫的导航栏
2015/09/23 HTML / CSS
HTML5 通信API 跨域门槛将不再高、数据推送也不再是梦
2013/04/25 HTML / CSS
AmazeUI 网格的实现示例
2020/08/13 HTML / CSS
Fanatics英国官网:美国体育电商
2018/11/06 全球购物
博柏利美国官方网站:Burberry美国
2020/11/19 全球购物
2013年军训通讯稿
2014/02/05 职场文书
文明美德伴我成长演讲稿
2014/05/12 职场文书
农村党支部书记司法四风问题对照检查材料
2014/09/26 职场文书
学校运动会广播稿范文
2014/10/02 职场文书
市级三好生竞选稿
2015/11/21 职场文书