共计 4456 个字符,预计需要花费 12 分钟才能阅读完成。
自动写代码机器人,免费开通
这篇文章主要介绍了 redis 怎样实现订单自动过期功能,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让丸趣 TV 小编带着大家一起了解一下。
文章背景
我们的目的是在用户下单后,规定指定时间后自动将订单设置为“已过期”,不能再发起支付。
思路:
结合 Redis 的订阅、发布和键空间通知机制(Keyspace Notifications)进行实现。
配置 redis.confg
notify-keyspace-events 选项默认是不启用,改为 notify-keyspace-events“Ex”。重启生效,索引位 i 的库,每当有过期的元素被删除时,向 **keyspace@:expired** 频道发送通知。
E 表示键事件通知,所有通知以__keyevent@__:expired 为前缀;
x 表示过期事件,每当有过期被删除时发送。
与 SpringBoot 进行集成
1、注册 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);
}
2、注册监听器
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) {// 过期事件处理流程}
3、配置订阅对象
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) 方法。
感谢你能够认真阅读完这篇文章,希望丸趣 TV 小编分享的“redis 怎样实现订单自动过期功能”这篇文章对大家有帮助,同时也希望大家多多支持丸趣 TV,关注丸趣 TV 行业资讯频道,更多相关知识等着你来学习!
向 AI 问一下细节