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缓存-序列化对象存储乱码问题的解决
Jun 21 Redis
聊一聊Redis与MySQL双写一致性如何保证
Jun 26 Redis
使用Redis实现实时排行榜功能
Jul 02 Redis
缓存替换策略及应用(以Redis、InnoDB为例)
Jul 25 Redis
基于Redis的List实现特价商品列表功能
Aug 30 Redis
linux下安装redis图文详细步骤
Dec 04 Redis
Redis实战高并发之扣减库存项目
Apr 14 Redis
Redis特殊数据类型Geospatial地理空间
Jun 01 Redis
使用Redis实现分布式锁的方法
Jun 16 Redis
浅谈Redis变慢的原因及排查方法
Jun 21 Redis
Redis实战之Lettuce的使用技巧详解
Dec 24 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中的session永不过期的解决思路及实现方法分享
2011/04/20 PHP
允许phpmyadmin空密码登录的配置方法
2011/05/29 PHP
PHP循环结构实例讲解
2014/02/10 PHP
Thinkphp模板中截取字符串函数简介
2014/06/17 PHP
一个非常完美的读写ini格式的PHP配置类分享
2015/02/12 PHP
学习php设计模式 php实现命令模式(command)
2015/12/08 PHP
PHP微信开发之文本自动回复
2016/06/23 PHP
轻松实现php文件上传功能
2017/02/17 PHP
js相册效果代码(点击创建即可)
2013/04/16 Javascript
Mac/Windows下如何安装Node.js
2013/11/22 Javascript
extjs4 treepanel动态改变行高度示例
2013/12/17 Javascript
js实现编辑div节点名称的方法
2014/12/17 Javascript
九种原生js动画效果
2015/11/11 Javascript
jquery读写cookie操作实例分析
2015/12/24 Javascript
移动端 一个简单易懂的弹出框
2016/07/06 Javascript
AngularJs Forms详解及简单示例
2016/09/01 Javascript
详解@Vue/Cli 3 Invalid Host header 错误解决办法
2019/01/02 Javascript
JavaScript递归函数定义与用法实例分析
2019/01/24 Javascript
react PropTypes校验传递的值操作示例
2020/04/28 Javascript
Vue 使用typescript如何优雅的调用swagger API
2020/09/01 Javascript
Vue+Spring Boot简单用户登录(附Demo)
2020/11/12 Javascript
python使用PyFetion来发送短信的例子
2014/04/22 Python
Python文件操作基本流程代码实例
2017/12/11 Python
Python Django 封装分页成通用的模块详解
2019/08/21 Python
Python基于codecs模块实现文件读写案例解析
2020/05/11 Python
python super()函数的基本使用
2020/09/10 Python
css3绘制百度的小度熊
2018/10/29 HTML / CSS
5分钟实现Canvas鼠标跟随动画背景
2019/11/18 HTML / CSS
人事主管岗位职责范本
2013/12/04 职场文书
爱岗敬业演讲稿
2014/05/05 职场文书
银行纠风工作实施方案
2014/06/08 职场文书
环境科学专业求职信
2014/08/04 职场文书
2015年小学体育工作总结
2015/05/22 职场文书
房屋转让协议书(标准范本)
2016/03/21 职场文书
Python如何把不同类型数据的json序列化
2021/04/30 Python
关于python类SortedList详解
2021/09/04 Python