延迟队列实现30分钟订单自动过期失效
延迟队列实现30分钟订单自动过期失效
- 1.首先Order实体类得实现Delayed接口
- 2.创建延迟服务类
- 3.使用
有一天,公司项目需求让用户订单未支付超过30分钟,自动取消订单状态.
我仔细想想用定时器?每分钟跑一下?显然不够优雅.
旁边同事看到我焦头烂额,有没有任何思绪.
突然扔给我两个文件,即高效又优雅的解决了我的问题,
我如获至宝,现在分享给大家.
1.首先Order实体类得实现Delayed接口
public class TjOrder implements Delayed, Serializable {// ....省略好多字段/*** 传入进来排序的实例*/@Overridepublic int compareTo(Delayed o) {if (this == o) {return 0;}TjOrder order= (TjOrder) o;long time = this.createTime.getTime() - order.getCreateTime().getTime();return time == 0 ? 0 : time < 0 ? -1 : 1;}/*** 取出处理过期订单*/@Overridepublic long getDelay(TimeUnit unit) {// ORDER_TIME_OUT = 1800000Lreturn (this.createTime.getTime() + ConstantsUtil.ORDER_TIME_OUT) - System.currentTimeMillis();}/*** 重写用于删除*/@Overridepublic boolean equals(Object obj) {if (this == obj) {return true;}if (obj == null) {return false;}TjOrder other = (TjOrder) obj;if (other.getOrderNo() == null) {return false;} else if (!id.equals(other.getId())) {return false;} else if (!orderNo.equals(other.getOrderNo())) {return false;}return true;}
}
2.创建延迟服务类
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.util.Date;
import java.util.List;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicBoolean;@Service
public class DelayService implements InitializingBean {Logger logger = LoggerFactory.getLogger(this.getClass());private static DelayQueue<TjOrder> delayQueue = new DelayQueue<TjOrder>();private static AtomicBoolean start = new AtomicBoolean(false);// 线程池private static ThreadFactory threadFactory = new ThreadFactoryBuilder().setNameFormat("useragent-pool-%d").build();private static ExecutorService executorService = new ThreadPoolExecutor(3, // 核心线程池大小6, // 最大线程池大小60L, // 线程最大空闲时间TimeUnit.MILLISECONDS, // 时间单位(毫秒)new LinkedBlockingQueue<Runnable>(), // 线程等待队列threadFactory, // 线程创建工厂new ThreadPoolExecutor.CallerRunsPolicy() // 拒绝策略);@Autowiredprivate TjOrderService tjOrderService;@Overridepublic void afterPropertiesSet() throws Exception {start();}public <T> void start() {if (start.get()) {return;}start.set(true);//放入待付款订单TjOrder order = new TjOrder();// -1 未支付,常量池状态order.setState(ConstantsUtil.ORDER_STATE_CREATE);List<TjOrder> list = tjOrderService.getList(order);list.forEach(item -> delayQueue.add(item));executorService.submit(() -> {// 取消订单while (start.get()) {try {TjOrder order = delayQueue.take();if (order != null) {// 订单过期TjOrder updateOrder = new TjOrder();updateOrder.setId(order.getId());// 常量池取消状态updateOrder.setState(ConstantsUtil.ORDER_STATE_CANCEL);tjOrderService.update(updateOrder);// 还原logger.info("=======订单号为[" + order.getOrderNo() + "]未支付过期,过期时间为:" + DateUtil.getNowStringTime() + "=======");}} catch (Exception e) {}}});}public void add(TjOrder order) {logger.info("加入订单队列订单号===={}", order.getOrderNo());if (!start.get()) {throw new RuntimeException("订单服务还未启动");}delayQueue.add(order);}public void delete(TjOrder order) {if (!start.get()) {throw new RuntimeException("订单服务还未启动");}delayQueue.remove(order);}public int getSize() {if (!start.get()) {throw new RuntimeException("订单服务还未启动");}return delayQueue.size();}}
3.使用
// 放入延迟队列
DelayService delayService = new DelayService();
delayService.add(order);
延迟队列实现30分钟订单自动过期失效相关推荐
- windows 远程 登录无操作30分钟后自动退出登录_【计时优易学车远程教育学习流程】...
重要通知: 1.2020年11月21日之后报名的学员,目前不需要到驾校学习科目一(4小时)及科目四(2小时),可直接用优易学车app远程教育学习,请12月6日之前尽快将科目一及科目四学时学完,如后期有 ...
- PHP与redis队列实现电商订单自动确认收货
一.场景 之前做的电商平台,用户在收到货之后,大部分都不会主动的点击确认收货,导致给商家结款的时候,商家各种投诉,于是就根据需求,要做一个订单在发货之后的x天自动确认收货.所谓的订单自动确认收货,就是 ...
- windows 远程 登录无操作30分钟后自动退出登录_Mac电脑如何远程Windows10
使用Mac电脑的你如何远程控制Win10电脑呢?相信好多人都是一头雾水,不知如何下手.这里小编为大家带来了一款非常不错的微软远程连接软件Microsoft Remote Desktop for mac ...
- Redis key过期事件监听实现 - 30分钟自动取消未支付订单
目录 一.前言 二.实现方案分析 三.Redis key过期事件方案实现步骤 3.1 Redis 安装步骤详见 3.2 修改 Redis 配置 3.3 在获取支付链接视图中设置key过期事件 3.4 ...
- 从零开发短视频电商 30分钟未支付订单自动关闭、七天自动确认收货等延迟任务问题
文章目录 常见延迟任务 常见解决方案 主动形式 被动形式 基于Redis实现ZSet的方式.键空间通知的方式 ZSet的方式 键空间通知的方式 RocketMQ延迟消息 延迟消息级别配置 客户端发送延 ...
- 【RabbitMq04】延迟队列
一.延迟队列理解 1.延迟队列概念 延时队列,队列内部是有序的,最重要的特性就体现在它的延时属性上,延时队列中的元素是希望在指定时间到了以后或之前取出和处理,简单来说,延时队列就是用来存放需要在指定时 ...
- Springboot使用DelayQueue实现订单自动取消
DelayQueue小结 DelayQueue是一个有序的无界BlockingQueue,用于放置实现了Delayed接口的对象,其中的对象在到期时才能从队列中取走. DelayQueue只能添加实现 ...
- 一款实用延迟队列的自研历程
文章原创作者:北京哗啦啦 基础架构部架构师 王晓鹏 文章推荐人:程超 一.背景 一款技术产品必定有其使用场景,不然代码写的再好也没有用武之地,那么首先我们要先来了解一下,在什么情况下会用到延迟队列呢? ...
- 面试官问:生成订单30分钟未支付,则自动取消,该怎么实现?
欢迎关注方志朋的博客,回复"666"获面试宝典 来源 | https://blog.csdn.net/hjm4702192/article/details/80519010 在开发 ...
- 订单30分钟未支付自动取消怎么实现?
本文已经收录到Github仓库,该仓库包含计算机基础.Java核心知识点.多线程.JVM.常见框架.分布式.微服务.设计模式.架构等核心知识点,欢迎star~ 地址:https://github.co ...
最新文章
- 遗传算法介绍和遗传算法的python实现
- 判断一个整数是否是水仙花数 || 编写程序,根据输入的月份和年份,求出该月的天数(1-12)|| 运算符的优先级问题 ||输出小写的a-z以及大写的Z—A||求出1-1/2+1/3-1/4…..1/
- boost::geometry模块自定义多边形示例
- Linux基础命令---comm
- 【送书】2021年哪些好书值得读(小姐姐配音)
- 【算法设计与分析】06 几类重要的函数
- Linux集群架构(LVS DR模式搭建、keepalived + LVS)
- 干货收藏!一文看懂8个常用Python库从安装到应用
- 视频处理简单实例 [OpenCV 笔记2]
- js中的浅拷贝深拷贝深入理解
- mui点击添加类名_Mui使用jquery并且使用点击跳转新窗口的实例
- (操作系统)系统调用讨论
- 前端项目实战5:聊天对话框
- if else 条件语句
- 计算机毕业设计-SSM企业OA管理系统-JavaWeb企业OA管理系统
- 自考多媒体计算机技术,自考多媒体计算机技术.doc
- android蓝牙键盘光标,罗技K810背光蓝牙键盘快捷键大全
- VMware出现“该虚拟机似乎正在使用中”问题
- 2017年《What Hi-Fi?》杂志评选KEF成最大赢家
- 预测房价实验-房价数据集