使用quartz定时任务实现支付单自动关单功能,并引入多线程+分段解决扫表延迟的问题
背景 我负责的订单系统模块,有一个功能就是需要实现订单的到期自动关闭,这功能以前其实是有的,但是后来我发现经常有一些订单,明明已经到期了,但是还是没有正常被关闭,就导致已超时的订单后来有支付成功的情况。 后来经过排查,是因为之前的实现方式比较简单,是基于JDK自带的delayQueue实现的,大致的代码如下: 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 import java.util.concurrent.DelayQueue; import java.util.concurrent.Delayed; import java.util.concurrent.TimeUnit; class Order implements Delayed { private String orderId; private long createTime; private long closeTime; public Order(String orderId, long delayInMinutes) { this.orderId = orderId; this.createTime = System.currentTimeMillis(); this.closeTime = this.createTime + TimeUnit.MINUTES.toMillis(delayInMinutes); } public String getOrderId() { return orderId; } @Override public long getDelay(TimeUnit unit) { long delay = closeTime - System.currentTimeMillis(); return unit.convert(delay, TimeUnit.MILLISECONDS); } @Override public int compareTo(Delayed other) { if (this == other) return 0; long diff = getDelay(TimeUnit.MILLISECONDS) - other.getDelay(TimeUnit.MILLISECONDS); return (int) (diff); } } public class OrderAutoCloser { public static void main(String[] args) { DelayQueue<Order> delayQueue = new DelayQueue<>(); // 创建订单并将其添加到DelayQueue中 Order order1 = new Order("Order1", 30); // 30分钟后自动关闭 Order order2 = new Order("Order2", 15); // 15分钟后自动关闭 delayQueue.offer(order1); delayQueue.offer(order2); // 启动后台线程来处理订单关闭 Thread closerThread = new Thread(() -> { while (true) { try { Order order = delayQueue.take(); System.out.println("Closing order: " + order.getOrderId()); // 在这里执行订单关闭的逻辑 } catch (InterruptedException e) { e.printStackTrace(); } } }); closerThread.start(); } } 在创建订单的时候,就指定好自动关闭的时间,并且把订单放入delayQueue中,借助delayQueue来实现到期关闭的功能。 ...