浅谈Redis中的自动过期机制
Redis中的自动过期机制
实现需求:处理订单过期自动取消,比如下单30分钟未支付自动更改订单状态
1.使用Redis Key自动过期出发事件通知
2.使用定时任务30分钟后检查
3.按照每分钟轮训检查
`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配置文件
2. 在配置文件中查找notify-keyspace-events
3. 修改为notify-keyspace-events Ex
4.重启redis
二、SpringBoot整合key失效监听
public class RedisListenerConfig {
@Bean
RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory) {
RedisMessageListenerContainer container = new RedisMessageListenerContainer();
container.setConnectionFactory(connectionFactory);
return container;
}
}
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;
/**
* 使用该方法监听 当我们的key失效的时候执行该方法
*
* @param message
* @param pattern
*/
@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
}
}
}
public class MemberController {
@Autowired
private UserMapper userMapper;
/**
*
* @return
*/
@RequestMapping(“/getListMember”)
@Cacheable(cacheNames = “member”, key = “‘getListMember'”)
public List<MemberEntity> getListMember() {
return userMapper.findMemberAll();
}
}
public class OrderEntity {
private Long id;
private String orderName;
/**
* 0 待支付 1 已经支付
*/
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;
}
}
@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.再次查看数据库,状态已被修改