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!