delayQueue实现订单超时自动取消
目录
- 说明
- 实现
- 1.编写Delayed实现类
- 2.编写DelayQueue业务类
- 3.编写订单业务逻辑
- 总结说明
说明
商城系统的订单模块都应该有:订单未支付超时后自动取消订单的操作。我们在开发过程中实现该功能也有很多,例如 消息中间件、定时任务等,每种方法都有各自的优点。这里我使用java DelayQueue容器来实现,优点是本地存储,系统资源消耗低,缺点是单机模式。
实现
1.编写Delayed实现类
@Data
@Accessors(chain = true)
@NoArgsConstructor
public class OrderAutoEntity implements Delayed {//订单编号private String orderNo;//订单具体的过期时间private long expire;//订单过期时间间隔定义(毫秒),这里设置30分钟public static final long expireTime = TimeUnit.MINUTES.toMillis(30);public OrderAutoEntity(String orderNo, LocalDateTime orderTime) {this.orderNo = orderNo;//转成毫秒long creatTime = orderTime.toInstant(ZoneOffset.of("+8")).toEpochMilli();this.expire = expireTime + creatTime;}/*** 获取剩余时间*/@Overridepublic long getDelay(TimeUnit unit) {return unit.convert(expire - System.currentTimeMillis(), TimeUnit.MILLISECONDS);}@Overridepublic int compareTo(Delayed other) {return (int) (this.getDelay(TimeUnit.MILLISECONDS) - other.getDelay(TimeUnit.MILLISECONDS));}}
2.编写DelayQueue业务类
@PostConstruct 这个注解会让标注的方法在系统启动后自定加载
@Service
@Slf4j
public class OrderCanelService {//订单增删改查业务逻辑@Resourceprivate OrderService orderService;//用于存放需要未支付计时订单private final static DelayQueue<OrderAutoEntity> delayQueue = new DelayQueue<>();//订单取消,数据库改变订单状态,DelayQueue容器移除该订单记录public void cancelOrder(String orderNo) {//数据库改变订单状态orderService.cancelOrder(orderNo);//容器遍历找到对应的订单记录,并从容器中移除Iterator val = delayQueue.iterator();while (val.hasNext()) {OrderAutoEntity orderAutoEntity = (OrderAutoEntity) val.next();if(orderAutoEntity.getOrderNo().equals(orderNo)){delayQueue.remove(orderAutoEntity);}}}//往队列中新增订单记录public void add(OrderAutoEntity orderAutoEntity) {delayQueue.put(orderAutoEntity);}/*** 服务器启动时,自动加载待支付订单*/@PostConstructpublic void initOrderStatus() {log.info(">>>>>>>>>>> 系统启动时,加载所有待支付订单到延时队列 >>>>>>>>>>>>.");//未支付订单查询QueryWrapper<Order> wrapper = new QueryWrapper();wrapper.select("order_no", "create_time").eq("status", "0");//获取所有未支付订单,这里用了mybatisplus操作数据库List<Map<String, Object>> orders = orderService.listMaps(wrapper);//逐个构造Delay的实现类,添加进容器for (Map<String, Object> order : orders) {Timestamp createTime = (Timestamp) order.get("create_time");OrderAutoEntity orderAutoEntity = new OrderAutoEntity((String) order.get("order_no"), createTime.toLocalDateTime());delayQueue.add(orderAutoEntity);}//启动一个线程持续健康订单超时Executors.newSingleThreadExecutor().execute(() -> {try {while (true) {if (delayQueue.size() > 0) {//容器中超时的订单记录会被取出OrderAutoEntity order = delayQueue.take();//修改数据库,容器中移除数据cancelOrder(order.getOrderNo());}}} catch (InterruptedException e) {log.error("InterruptedException error:", e);}});}
}
3.编写订单业务逻辑
需要朱阿姨的是:我们前台每次新增订单时,也需要再给容器中添加一条记录。
@RestController
@Slf4j
@RequestMapping("/api")
public class OrderController {@Resourceprivate OrderCanelService orderCanelService ;...//前端页面调用的订单新增接口@PostMapping("/order")@Transactional(rollbackFor = Exception.class)public ResponseEntity addOrder(@RequestBody Map<String, Object> params) {...//构造订单延时类(OrderAutoEntity),这里是伪代码OrderAutoEntity orderAutoEntity = new OrderAutoEntity(orderNo, createTime);orderCanelService.add(orderAutoEntity);...}...
}
总结说明
我这种操作只支持单机情况,一般还可以进一步优化,利用redis:在新增订单时,除了存到数据库,再保留一份到redis中,这样我们在OrderCanelService 的初始化函数initOrderStatus中就不需要查数据库,每次启动就直接读redis中的数据。这里我就没做这么复杂。
delayQueue实现订单超时自动取消相关推荐
- 使用DelayQueue模拟订单超时自动取消
1.创建能在DelayQueue中存放的Order对象 package com.example.javastudy.delay_queue;import java.time.Duration; imp ...
- 订单超时自动取消3种方案——我们用这种!
大家好,大家对电商购物应该都比较熟悉了,我们应该注意到,在下单之后,通常会有一个倒计时,如果超过支付时间,订单就会被自动取消. 下单 今天,我们来聊聊订单超时未支付自动取消的几种方案. 1.定时任务 ...
- Java 实现订单未支付超时自动取消
在电商上购买商品后,如果在下单而又没有支付的情况下,一般提示30分钟完成支付,否则订单自动.比如在京东下单为完成支付: 超过24小时,就会自动取消订单,下面使用 Java 定时器实现超时取消订单功能. ...
- TP6订单待支付超时自动取消
1:安装redis 2:安装think-queue composer require topthink/think-queue 3:设置配置文件,使用redis进行存储,文件位置config/queu ...
- 订单过期 自动取消实现方案
在电商.支付等领域,往往会有这样的场景,用户下单后放弃支付了,那这笔订单会在指定的时间段后进行关闭操作,细心的你一定发现了像某宝.某东都有这样的逻辑,而且时间很准确,误差在1s内:那他们是怎么实现的呢 ...
- 【Java并发编程】20、DelayQueue实现订单的定时取消
当订单定时取消需要修改数据库订单状态,但是怎么确定订单什么时候应该改变状态,解决方案有下面两种: 第一种,写个定时器去每分钟扫描数据库,这样更新及时,但是如果数据库数据量大的话,会对数据库造成很大的 ...
- java订单到期自动取消_订单自动过期实现方案
需求分析: 24小时内未支付的订单过期失效. 解决方案 被动设置:在查询订单的时候检查是否过期并设置过期状态. 定时调度:定时器定时查询并过期需要过期的订单. 延时队列:将未支付的订单放入一个延时队列 ...
- springboot整合RabbitMQ实现延时自动取消订单
1.pom依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>s ...
- DelayQueue延迟任务队列----实现订单超时修改订单状态处理,复制即用
其实实现这种功能的方式有很多种MQ,Redis,以及DelayQueue,也是比较常见的. 如果完全没啥要求,而且服务器配置又好,也不在乎有没有空隙,那还可以采用定时任务做处理,直接定时刷数据库,但是 ...
最新文章
- 机器学习中的7种数据偏见
- FLAC3D可视化后处理matlab,一种基于Matlab的由Midas导入Flac3D的模型识别方法与流程...
- 唐尼vr眼镜好吗_科普:眼镜片有哪些种类?镜片越薄越好吗?无框眼镜配什么材质?...
- java调用shell脚本及注意事项
- 一步一步写算法(之 算法总结)【转】
- java 语法 —— 数组
- Flask知识点查阅
- AI空谈情怀,也是要输的 | 人机辩论大战
- zabbix_nginx监控
- 把html转换成word,怎么把html转换成word
- STM32硬件CRC计算CRC8
- 给大家贴一点好东东 喜欢电影的朋友请看
- 【华为】verilog语言编写规范(一)
- 未来计算机的图片大全集,小学生未来的机器人儿童画图片大全
- 时间戳与日期相互转换
- Dagger2 使用详解
- 前端Number转千位符以及反转
- 一个很不错的bash脚本编写教程
- 最新最火的十大网络流行语排行榜火热出炉,幽默搞笑网络段子来袭!
- OSChina 周三乱弹 —— 我胖我吃你家饭了吗
热门文章
- 率土之滨鸿蒙之初,率土之滨黑科技第5期:上阵姐妹花,S1赛季大小乔吊打大汉弓...
- Pinhole camera model相机模型
- 手机通讯录联系人恢复?没有备份的你需要知道
- 图片验证码kaptcha
- p74 应急响应-winlinux 分析后门勒索病毒攻击
- 【Hack The Box】windows练习-- Timelapse
- 虚拟机中的SQL server使用NetDrive附加位于网络驱动器或远程地址的MDF数据库文件...
- input框灰色提示字,输入时提示字消失
- 2020年UI设计4大趋势全方位分析!
- 物联网时代_智能门锁市场前景被看好