redis實(shí)現(xiàn)訂單自動(dòng)過期功能的源碼分享

redis實(shí)現(xiàn)訂單自動(dòng)過期功能的源碼分享

文章背景

我們的目的是在用戶下單后,規(guī)定指定時(shí)間后自動(dòng)將訂單設(shè)置為“已過期”,不能再發(fā)起支付。

(學(xué)習(xí)視頻分享:redis視頻教程

思路:

結(jié)合redis的訂閱、發(fā)布和鍵空間通知機(jī)制(Keyspace Notifications)進(jìn)行實(shí)現(xiàn)。

配置redis.confg

notify-keyspace-events選項(xiàng)默認(rèn)是不啟用,改為notify-keyspace-events “Ex”。重啟生效,索引位i的庫(kù),每當(dāng)有過期的元素被刪除時(shí),向**keyspace@:expired**頻道發(fā)送通知。
E表示鍵事件通知,所有通知以__keyevent@__:expired為前綴;
x表示過期事件,每當(dāng)有過期被刪除時(shí)發(fā)送。

與SpringBoot進(jìn)行集成

1、注冊(cè)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、注冊(cè)監(jiān)聽器

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、配置訂閱對(duì)象

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);         // 監(jiān)聽paymentDataBase 庫(kù)的過期事件         String subscribeChannel = "__keyevent@" + paymentDataBase + "__:expired";         container.addMessageListener(listenerAdapter, new PatternTopic(subscribeChannel));         return container; 	} 	 	@Bean     MessageListenerAdapter listenerAdapter() {         return new MessageListenerAdapter(paymentListener);     } }

paymentDataBase 庫(kù)元素過期后就會(huì)跳入PaymentListener 的onMessage(Message message, byte[] pattern)方法。

相關(guān)推薦:redis視頻教程

以上就是

? 版權(quán)聲明
THE END
喜歡就支持一下吧
點(diǎn)贊5 分享