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基本命令与使用场景
Jun 01 Redis
你真的了解redis为什么要提供pipeline功能
Jun 22 Redis
redis 存储对象的方法对比分析
Aug 02 Redis
Redis Cluster 集群搭建你会吗
Aug 04 Redis
使用RedisTemplat实现简单的分布式锁
Nov 20 Redis
linux下安装redis图文详细步骤
Dec 04 Redis
muduo TcpServer模块源码分析
Apr 26 Redis
Redis特殊数据类型bitmap位图
Jun 01 Redis
Redis特殊数据类型Geospatial地理空间
Jun 01 Redis
Redis入门基础常用操作命令整理
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
文章推荐系统(二)
2006/10/09 PHP
ob_start(),ob_start('ob_gzhandler')使用
2006/12/25 PHP
解析smarty 截取字符串函数 truncate的用法介绍
2013/06/20 PHP
PHP中error_reporting()用法详解
2015/08/31 PHP
浅谈PHP中如何实现Hook机制
2017/11/14 PHP
PHP基于cookie实现统计在线人数功能示例
2019/01/16 PHP
laravel按天、按小时,查询数据的实例
2019/10/09 PHP
javascript css styleFloat和cssFloat
2010/03/15 Javascript
JS实现点击复选框将按钮或文本框变为灰色不可用的方法
2015/08/11 Javascript
JS实现的倒计时效果实例(2则实例)
2015/12/23 Javascript
jquery点击改变class并toggle的实现代码
2016/05/15 Javascript
深入理解jQuery之事件移除
2016/06/02 Javascript
JavaScript第一篇之实现按钮全选、功能
2016/08/21 Javascript
getElementById().innerHTML与getElementById().value的区别
2016/10/27 Javascript
JavaScript之Date_动力节点Java学院整理
2017/06/28 Javascript
Angularjs上传文件组件flowjs功能
2017/08/07 Javascript
详解Eslint 配置及规则说明
2018/09/10 Javascript
vue实现前台列表数据过滤搜索、分页效果
2019/05/28 Javascript
python使用循环实现批量创建文件夹示例
2014/03/25 Python
python学习教程之Numpy和Pandas的使用
2017/09/11 Python
为什么选择python编程语言入门黑客攻防 给你几个理由!
2018/02/02 Python
Python基础教程之利用期物处理并发
2018/03/29 Python
Python最小二乘法矩阵
2019/01/02 Python
python多个模块py文件的数据共享实例
2019/01/11 Python
pybind11和numpy进行交互的方法
2019/07/04 Python
Python使用scipy模块实现一维卷积运算示例
2019/09/05 Python
Python FFT合成波形的实例
2019/12/04 Python
python已协程方式处理任务实现过程
2019/12/27 Python
python实现简单的tcp 文件下载
2020/09/16 Python
非功能性需求都包括哪些方面
2013/10/29 面试题
应届生人事助理求职信
2013/11/09 职场文书
家长通知书家长评语
2014/04/17 职场文书
中学生爱国演讲稿
2014/09/05 职场文书
民主生活会剖析材料
2014/09/30 职场文书
2015年国庆节标语大全
2015/07/30 职场文书
煤矿隐患排查制度
2015/08/05 职场文书