实现需求:处理订单过期自动取消,比如下单30分钟未支付自动更改订单状态
实现方案:
使用Redis Key自动过期触发事件通知
使用定时任务30分钟后检查
按照每分钟轮训检查
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中配置:notify-keyspace-events Ex
二、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);
}
/**
* 待支付
*/
private static final Integer ORDER_STAYPAY = 0;
/**
* 失效
*/
private static final Integer ORDER_INVALID = 2;
@Autowired
private OrderMapper orderMapper;
/**
* Redis失效事件 key
*
* @param message
* @param pattern
*/
@Override
public void onMessage(Message message, byte[] pattern) {
String expiraKey = message.toString();
// 根据key查询 value 如果还还是为待支付状态 将订单改为已经超时~~
OrderEntity orderNumber = orderMapper.getOrderNumber(expiraKey);
System.out.println(expiraKey);
if (orderNumber == null) {
return;
}
if (orderNumber.getOrderStatus().equals(ORDER_STAYPAY)) {
// 将订单状态改为已经失效
orderMapper.updateOrderStatus(expiraKey, ORDER_INVALID);
}
}
}
@RestController
public class OrderController {
@Autowired
private OrderMapper orderMapper;
@Autowired
private RedisUtils redisUtils;
@RequestMapping("/saveOrder")
public String saveOrder() {
// 1.生成token
String orderToken = UUID.randomUUID().toString();
String orderId = System.currentTimeMillis() + "";
//2. 将该token存放到redis中
redisUtils.setString(orderToken, orderId, 5L);
OrderEntity orderEntity = new OrderEntity(null, "会员", orderId, orderToken);
int result = orderMapper.insertOrder(orderEntity);
return result > 0 ? "success" : "fail";
}
}
@Data
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;
}
}
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);
}
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!