How to realize the function of automatically closing orders?

Business scenario
Let's take the order function as an example to illustrate: the order will be automatically closed if it is not paid for a period of time after the order is generated. The simplest idea is to set up polling for timed tasks, but the creation time of each order is different, and the rules for timed tasks cannot be set. If the interval of timed task execution is set too short, it will affect efficiency too much. Another idea is to judge the time to perform related operations when the user enters the order interface. There may be many ways, here is a way to monitor the expiration time of the Redis key-value pair to realize the automatic closing of the order

Implementation Ideas
When generating an order, add a KV key-value pair to Redis, where K is the order number, and ensure that an order in the database can be located through K, and V can be any value. Suppose that when the order is generated, K is the order number and V is the key-value pair of the order number, and the expiration time is set to 30 minutes. If the key-value pair expires after 30 minutes, a notification can be sent to the program, or Implement a method, then the order closing problem can be solved. Implementation: It is implemented by monitoring the expiration queue provided by Redis. After monitoring the expiration queue, if a KV key-value pair in Redis expires, then a message will be sent to the listener, and the listener can get the K of the key-value pair. Note , V cannot be obtained because it has expired. This is the reason mentioned above, why it is necessary to ensure that the order can be located through K, and V can be any value. After getting K, locate the order through K and determine its status. If it is unpaid, update it to closed or cancel the status.

Enable Redis key expiration reminder
Modify redis related event configuration. Find the redis configuration file redis.conf, check the notify-keyspace-events configuration item, if not, add notify-keyspace-events Ex, if there is a value, add Ex, the related parameters are described as follows:

K: keyspace event, the event is issued with keyspace@ as the prefix
E: keyevent event, the event is issued with the keyevent@ prefix
g: general, non-specific commands, such as del, expire, rename, etc
.: string specific commands l: List specific commands s: Set specific commands h: Hash specific commands z: Ordered set specific commands x: Expiration event, this event will be generated when a key expires and is deleted e: Eviction event, when a key factor When the maxmemore policy is deleted, the event A is generated: g: string specific command l: list specific command s: set specific command h: hash specific command z: ordered set specific command x: expiration event, when a certain key This event will be generated when it expires and is deleted. e: Eviction event. When a key is deleted due to the maxmemore strategy, the event A: g: Character character string Laid specified command command L : listed in Table Laid- specified command command S : set engagement Laid specified command command H : Ha Greek Patent specified command command Z : There sequence set engagement Laid specified command command X : over of things member , when a one button over period and deleted except when will productionHealth the matter member E : drive by things member , when a number key due to m A X m E m O R & lt E policy strategy and is deleted in addition to the time , producing raw this matter member A : G lshzxe alias, so "AKE" means Follow all events,
introduce dependencies
, add org.springframework.boot:spring-boot-starter-data-redis dependencies in pom.xml

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
复制代码

Related configuration
Define and configure RedisListenerConfig to monitor the expiration time of Redis key

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;

@Configuration
public class RedisListenerConfig {

    @Bean
    RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory) {

        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);
        return container;
    }
}
复制代码

Define the listener RedisKeyExpirationListener, implement the KeyExpirationEventMessageListener interface, check the source code and find that the interface listens to all db expired events keyevent@*:expired"

import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.listener.KeyExpirationEventMessageListener;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.stereotype.Component;

/**
 * 监听所有db的过期事件__keyevent@*__:expired"
 */
@Component
public class RedisKeyExpirationListener extends KeyExpirationEventMessageListener {

    public RedisKeyExpirationListener(RedisMessageListenerContainer listenerContainer) {
        super(listenerContainer);
    }

    /**
     * 针对 redis 数据失效事件,进行数据处理
     * @param message
     * @param pattern
     */
    @Override
    public void onMessage(Message message, byte[] pattern) {

        // 获取到失效的 key,进行取消订单业务处理
        String expiredKey = message.toString();
        System.out.println(expiredKey);
    }
}

Reference: " 2020 latest Java basics and detailed video tutorials and learning routes!

Original link: https://juejin.cn/post/6919095552835584008

Guess you like

Origin blog.csdn.net/weixin_46699878/article/details/112832641