• 技术文章 >数据库 >Redis

    redis实现订单自动过期功能的源码分享

    VV2020-12-25 09:30:36转载546

    文章背景

    我们的目的是在用户下单后,规定指定时间后自动将订单设置为“已过期”,不能再发起支付。

    (学习视频分享:redis视频教程

    思路:

    结合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)方法。

    相关推荐:redis数据库教程

    以上就是redis实现订单自动过期功能的源码分享的详细内容,更多请关注php中文网其它相关文章!

    声明:本文转载于:csdn,如有侵犯,请联系admin@php.cn删除
    专题推荐:redis 订单 自动过期
    上一篇:怎么实现redis外网可访问 下一篇:windows系统添加和删除redis服务的方法
    大前端线上培训班

    相关文章推荐

    • 让CodeIgniter数据库缓存自动过期的处理的方法_PHP教程• codeigniter数据库缓存自动过期处理方法 • 怎么实现redis外网可访问• 详解laravel中redis的配置和使用

    全部评论我要评论

  • 取消发布评论发送
  • 1/1

    PHP中文网