前言:取消订单有很多种实现方式,通过redis来实时监测订单的状态变化,并及时处理相关事件,比如取消订单、重新上架商品等。通过这种方式,系统可以实现订单的自动管理,提高了系统的可靠性和效率。

前置准备

Redis工具类用来实现放入订单 过期通知

1
2
3
4
//订单放进去 key  过期时间:时间戳  订单号
public static void zadd(String key, double score, String member) {
RedisPool.getWriteJedis().zadd(key, score, member);
}

下单操作

1
2
3
4
5
6
7
8
9
public void addOrder(Model model) {
//新增订单其他操作。。。。。

//缓存进redis 新增订单 2小时过期时间
Calendar cal1 = Calendar.getInstance();
cal1.add(Calendar.HOUR, 2);
int timeStamp = (int) (cal1.getTimeInMillis() / 1000);
CacheTool.zadd("addOrder", timeStamp, String.valueOf(order.getId()));
}

取消订单

它首先获取一个用于读取数据的 Jedis 实例,然后进入一个无限循环。在每次循环中,它会遍历两个集合,分别检查是否有成员已经到期。如果某个成员的时间戳早于当前时间,它会将该成员从有序集合中移除,并执行相应的处理逻辑。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Tuple;

import java.util.Arrays;
import java.util.Calendar;
import java.util.HashSet;
import java.util.Set;

/**
* 用于监听新增订单和订单支付情况并处理
*
* @Author: Chang
* @create: 2023/03/28 15:22
*/
@Component
public class MyThread implements InitializingBean {

@Override
public void afterPropertiesSet() {
// 创建一个线程监听新增订单和订单支付情况
Thread thread = new Thread(() -> {
Jedis jedis = RedisPool.getReadJedis();
while (true) {
// 监听新增订单和订单支付事件
Set<String> keys = new HashSet<>(Arrays.asList("addOrder", "orderPay"));
for (String key : keys) {
// 从有序集合中获取成员及其分数
Set<Tuple> items = jedis.zrangeWithScores(key, 0, 1);
if (items == null || items.isEmpty()) {
// 如果集合为空,跳过当前集合的处理
continue;
}
Tuple item = items.iterator().next();
// 获取成员的分数(时间戳)
int score = (int) item.getScore();
Calendar cal = Calendar.getInstance();
// 获取当前时间的秒数
int nowSecond = (int) (cal.getTimeInMillis() / 1000);
if (nowSecond < score) {
// 如果当前时间早于成员代表的时间,跳过当前成员的处理
continue;
}
// 从集合中移除已处理的成员
Long num = jedis.zrem(key, item.getElement());
if (num == null || num <= 0) {
// 如果移除操作失败或未移除任何成员,跳过当前成员的处理
continue;
}
if ("addOrder".equals(key)) {
// 处理新增订单事件
handleAddOrder(item.getElement());
}
}
try {
// 休眠500毫秒
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}

});
thread.start();
}

/**
* 处理新增订单情况
*
* @param id 订单ID
*/
private void handleAddOrder(String id) {
//按订单id 查询订单信息
// 订单存在且为待支付状态
// 修改订单状态为已取消
// 重新上架商品
// 给客户发送系统消息
}
}