浅谈Redis中的自动过期机制

2022-11-13 08:11:01 过期 机制 浅谈

Redis中的自动过期机制

实现需求:处理订单过期自动取消,比如下单30分钟未支付自动更改订单状态

1.使用Redis Key自动过期出发事件通知
2.使用定时任务30分钟后检查
3.按照每分钟轮训检查

CREATE TABLE `order_number` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `order_name` varchar(255) DEFAULT NULL,
  `order_status` int(11) DEFAULT NULL,
  `order_token` varchar(255) DEFAULT NULL,
  `order_id` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=20 DEFAULT CHARSET=utf8;

一、使用Redis Key自动过期机制

当我们的key失效时,可以执行我们的客户端回调监听的方法。
需要在Redis中配置:

1.打开redis.conf配置文件

vi redis.conf

2. 在配置文件中查找notify-keyspace-events

/notify-keyspace-events

3. 修改为notify-keyspace-events Ex

4.重启redis

在

二、springBoot整合key失效监听

@Configuration
public class RedisListenerConfig {
    @Bean
    RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory) {
        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);
        return container;
    }
}
@Component
public class RedisKeyExpirationListener extends KeyExpirationEventMessageListener {
    public RedisKeyExpirationListener(RedisMessageListenerContainer listenerContainer) {
        super(listenerContainer);
    }

    @Resource
    private OrderMapper orderMapper;

    
    private static final Integer ORDER_STAYPAY = 0;

    
    private static final Integer ORDER_INVALID = 2;

    
    @Override
    public void onMessage(Message message, byte[] pattern) {
        String expiraKey = message.toString();
        System.out.println("该key:expiraKey:" + expiraKey + "失效啦~");
        // 前缀判断 orderToken
        OrderEntity orderNumber = orderMapper.getOrderNumber(expiraKey);
        if (orderNumber == null) {
            return;
        }
        // 获取订单状态
        Integer orderStatus = orderNumber.getOrderStatus();
        // 如果该订单状态为待支付的情况下,直接将该订单修改为已经超时
        if (orderStatus.equals(ORDER_STAYPAY)) {
            orderMapper.updateOrderStatus(expiraKey, ORDER_INVALID);
            // 库存加上1
        }
    }
}
@RestController
public class MemberController {
    @Autowired
    private UserMapper userMapper;

    
    @RequestMapping("/getListMember")
    @Cacheable(cacheNames = "member", key = "'getListMember'")
    public List<MemberEntity> getListMember() {
        return userMapper.findMemberAll();
    }
}
@Data
public class OrderEntity {
    private Long id;
    private String orderName;
    
    private Integer orderStatus;

    private String orderToken;
    private String orderId;

    public OrderEntity(Long id, String orderName, String orderId, String orderToken) {
        this.id = id;
        this.orderName = orderName;
        this.orderId = orderId;
        this.orderToken = orderToken;
    }
}
public interface OrderMapper {

    @Insert("insert into order_number values (null,#{orderName},0,#{orderToken},#{orderId})")
    int insertOrder(OrderEntity OrderEntity);


    @Select("SELECT ID AS ID ,order_name AS ORDERNAME ,order_status AS orderstatus,order_token as ordertoken,order_id as  orderid FROM order_number\n" +
            "where order_token=#{orderToken};")
    OrderEntity getOrderNumber(String orderToken);

    @Update("\n" +
            "\n" +
            "update order_number set order_status=#{orderStatus} where order_token=#{orderToken};")
    int updateOrderStatus(String orderToken, Integer orderStatus);
}

1.访问addOrder接口

2.查看数据库数据

3. 10s后redis过期,执行回调机制

4.再次查看数据库,状态已被修改

相关文章