Home  >  Article  >  Database  >  Source code sharing for redis to implement automatic order expiration function

Source code sharing for redis to implement automatic order expiration function

王林
王林forward
2020-12-25 09:30:361896browse

Source code sharing for redis to implement automatic order expiration function

Background of the article

Our purpose is to automatically set the order to "expired" after the specified time after the user places the order, and no further payment can be initiated.

(Learning video sharing: redis video tutorial)

Idea:

Combine Redis’s subscription, publishing and keyspace notification mechanism (Keyspace Notifications) To implement.

Configure redis.confg

The notify-keyspace-events option is not enabled by default, change it to notify-keyspace-events "Ex". It takes effect after restarting. The library with index position i will send a notification to the **keyspace@:expired** channel whenever an expired element is deleted.
E represents key event notification, all notifications are prefixed with __keyevent@__:expired;
x represents expiration event, which is sent whenever something expires and is deleted.

Integrate with SpringBoot

1. Register 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. Register listener

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. Configure subscription object

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 After the library element expires, it will jump to the onMessage(Message message, byte[] pattern) method of PaymentListener.

Related recommendations: redis database tutorial

The above is the detailed content of Source code sharing for redis to implement automatic order expiration function. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:csdn.net. If there is any infringement, please contact admin@php.cn delete