订单超时取消(通过Redis过期监听)

1. Redis安装

官网下载Redis

在这里插入图片描述

下载后解压

在这里插入图片描述

2. Redis过期监听的实现

2.1 修改配置

修改 redis.windows.conf 配置文件中 notify-keyspace-events 的值;默认配置 notify-keyspace-events 的值为 "";修改为 notify-keyspace-events Ex 即可开启过期事件

2.2 创建Redis配置类

package michael.spica.demo.redis;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

/**
 * redis监听配置
 * <p>
 * Created by michael on 2020/05/21.
 */
@Configuration
public class RedisListenerConfig {

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 处理乱码
     *
     * @return
     */
    @Bean
    public RedisTemplate redisTemplateInit() {
        // key序列化
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        // val实例化
        redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
        return redisTemplate;
    }

    @Bean
    public RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory) {
        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);
        return container;
    }
}

2.3 创建Redis过期事件的监听类

package michael.spica.demo.redis;

import lombok.extern.slf4j.Slf4j;
import michael.spica.demo.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.listener.KeyExpirationEventMessageListener;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.stereotype.Component;

/**
 * redis数据失效事件
 * <p>
 * 继承KeyExpirationEventMessageListener创建redis过期事件的监听类
 * <p>
 * Created by michael on 2020/05/21.
 */
@Slf4j
@Component
public class RedisKeyExpirationListener extends KeyExpirationEventMessageListener {

    public RedisKeyExpirationListener(RedisMessageListenerContainer listenerContainer) {
        super(listenerContainer);
    }
    
    @Autowired
    private OrderService orderService;

    @Override
    public void onMessage(Message message, byte[] pattern) {
        try {
            String key = message.toString();
            // 从失效key中筛选代表订单失效的key
            if (null != key && key.startsWith("order_")) {
                String orderNo = key.split("_")[1];
                // 查询订单,如果是未支付状态则为-取消订单
                orderService.cancel(orderNo);
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("修改支付订单过期状态异常:{}", e.getMessage());
        }
    }
}

orderService.cancel 方法:

public void cancel(String orderNo) {
    Optional.ofNullable(orderRepository.findByOrderNo(orderNo)).ifPresent(order -> {
        order.setOrderStatus(OrderStatus.CANCELLED);
        orderRepository.saveAndFlush(order);
        log.info("订单号为「{}」的订单超时未支付,已自动修改为「已取消」状态", orderNo);
    });
}

3. 测试

调用 orderService.create 方法创建测试订单

public void create(Integer nums) {
    IntStream.range(0, nums).forEach(i -> {
        Order order = new Order();
        order.setAmount(1000);
        order.setExpiryTime(Times.after(order.getCreationTime(), 30));// 订单创建时间+30分钟
        Order order_ = orderRepository.save(order);
        log.debug("订单创建成功:{}", JSONObject.toJSON(order_));

        // 存入redis
        String orderNo = order_.getOrderNo();
        redisService.save(ORDER_PREFIX + orderNo, orderNo, 30);

        try {
            Thread.sleep(3 * 1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    });
}

如下:
在这里插入图片描述
结果:
在这里插入图片描述

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值