目录

  • 说明
  • 实现
    • 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实现订单超时自动取消相关推荐

  1. 使用DelayQueue模拟订单超时自动取消

    1.创建能在DelayQueue中存放的Order对象 package com.example.javastudy.delay_queue;import java.time.Duration; imp ...

  2. 订单超时自动取消3种方案——我们用这种!

    大家好,大家对电商购物应该都比较熟悉了,我们应该注意到,在下单之后,通常会有一个倒计时,如果超过支付时间,订单就会被自动取消. 下单 今天,我们来聊聊订单超时未支付自动取消的几种方案. 1.定时任务 ...

  3. Java 实现订单未支付超时自动取消

    在电商上购买商品后,如果在下单而又没有支付的情况下,一般提示30分钟完成支付,否则订单自动.比如在京东下单为完成支付: 超过24小时,就会自动取消订单,下面使用 Java 定时器实现超时取消订单功能. ...

  4. TP6订单待支付超时自动取消

    1:安装redis 2:安装think-queue composer require topthink/think-queue 3:设置配置文件,使用redis进行存储,文件位置config/queu ...

  5. 订单过期 自动取消实现方案

    在电商.支付等领域,往往会有这样的场景,用户下单后放弃支付了,那这笔订单会在指定的时间段后进行关闭操作,细心的你一定发现了像某宝.某东都有这样的逻辑,而且时间很准确,误差在1s内:那他们是怎么实现的呢 ...

  6. 【Java并发编程】20、DelayQueue实现订单的定时取消

    当订单定时取消需要修改数据库订单状态,但是怎么确定订单什么时候应该改变状态,解决方案有下面两种:  第一种,写个定时器去每分钟扫描数据库,这样更新及时,但是如果数据库数据量大的话,会对数据库造成很大的 ...

  7. java订单到期自动取消_订单自动过期实现方案

    需求分析: 24小时内未支付的订单过期失效. 解决方案 被动设置:在查询订单的时候检查是否过期并设置过期状态. 定时调度:定时器定时查询并过期需要过期的订单. 延时队列:将未支付的订单放入一个延时队列 ...

  8. springboot整合RabbitMQ实现延时自动取消订单

    1.pom依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>s ...

  9. DelayQueue延迟任务队列----实现订单超时修改订单状态处理,复制即用

    其实实现这种功能的方式有很多种MQ,Redis,以及DelayQueue,也是比较常见的. 如果完全没啥要求,而且服务器配置又好,也不在乎有没有空隙,那还可以采用定时任务做处理,直接定时刷数据库,但是 ...

最新文章

  1. 机器学习中的7种数据偏见
  2. FLAC3D可视化后处理matlab,一种基于Matlab的由Midas导入Flac3D的模型识别方法与流程...
  3. 唐尼vr眼镜好吗_科普:眼镜片有哪些种类?镜片越薄越好吗?无框眼镜配什么材质?...
  4. java调用shell脚本及注意事项
  5. 一步一步写算法(之 算法总结)【转】
  6. java 语法 —— 数组
  7. Flask知识点查阅
  8. AI空谈情怀,也是要输的 | 人机辩论大战
  9. zabbix_nginx监控
  10. 把html转换成word,怎么把html转换成word
  11. STM32硬件CRC计算CRC8
  12. 给大家贴一点好东东 喜欢电影的朋友请看
  13. 【华为】verilog语言编写规范(一)
  14. 未来计算机的图片大全集,小学生未来的机器人儿童画图片大全
  15. 时间戳与日期相互转换
  16. Dagger2 使用详解
  17. 前端Number转千位符以及反转
  18. 一个很不错的bash脚本编写教程
  19. 最新最火的十大网络流行语排行榜火热出炉,幽默搞笑网络段子来袭!
  20. OSChina 周三乱弹 —— 我胖我吃你家饭了吗

热门文章

  1. 率土之滨鸿蒙之初,率土之滨黑科技第5期:上阵姐妹花,S1赛季大小乔吊打大汉弓...
  2. Pinhole camera model相机模型
  3. 手机通讯录联系人恢复?没有备份的你需要知道
  4. 图片验证码kaptcha
  5. p74 应急响应-winlinux 分析后门勒索病毒攻击
  6. 【Hack The Box】windows练习-- Timelapse
  7. 虚拟机中的SQL server使用NetDrive附加位于网络驱动器或远程地址的MDF数据库文件...
  8. input框灰色提示字,输入时提示字消失
  9. 2020年UI设计4大趋势全方位分析!
  10. 物联网时代_智能门锁市场前景被看好