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

前言

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

配置redis.confg

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

与SpringBoot进行集成

①注册JedisConnectionFactory

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667import 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; @Configurationpublic 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;} @Beanpublic 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);}}

②注册监听器

1234567891011121314import 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@Transactionalpublic void onMessage(Message message, byte[] pattern) {// 过期事件处理流程}}

③配置订阅对象

1234567891011121314151617181920212223242526272829303132333435363738394041import 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; @BeanRedisMessageListenerContainer redisMessageListenerContainer(MessageListenerAdapter listenerAdapter) {RedisMessageListenerContainer container = new RedisMessageListenerContainer();container.setConnectionFactory(connectionFactory);// 监听paymentDataBase 库的过期事件String subscribeChannel = "__keyevent@" + paymentDataBase + "__:expired";container.addMessageListener(listenerAdapter, new PatternTopic(subscribeChannel));return container;} @BeanMessageListenerAdapter listenerAdapter() {return new MessageListenerAdapter(paymentListener);}}

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

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

原创文章,作者:Zhu, Yuanyuan,如若转载,请注明出处:https://www.yidc.net/archives/16789