Java实现商城订单超时取消功能
作者:长路漫漫~Gavin 发布时间:2023-09-17 06:20:42
标签:商城,订单,超时,取消
大多数的B2C商城项目都会有限时活动,当用户下单后都会有支付超时时间,当订单超时后订单的状态就会自动变成已取消 ,这个功能的实现有很多种方法,本文的实现方法适合大多数比较小的商城使用。
实现原理:
利用 jdk 的 DelayQueue的阻塞队列的特性实现。在项目启动时开启一个线程处理 DelayQueue 队列里弹出的超时订单对象,订单未超时该线程处于等待中。
DelayQueue的简单介绍:
DelayQueue类的主要作用:是一个 * 的BlockingQueue,用于放置实现了Delayed接口的对象,其中的对象只能在其到期时才能从队列中取走。这种队列是有序的,即队头对象的延迟到期时间最长。注意:不能将null元素放置到这种队列中。
实现方式 :
1.创建一个实现Delayed接口的 order 类并重写compareTo和 getDelay方法
2.创建一个帮助类OrderCollection(订单的增删查)
3. 创建CancellOrder类
在生成订单时将订单号创建时间和过期时间封装成一个实现Delayed接口的对象存入DelayQueue队列中,当该订单支付完成后将该对象从队列中移除,(为了保证不丢失订单建议在项目启动时将数据库中的符合条件的订单初始化到DelayQueue队列中 )
实现代码如下:
/**
* 类说明
*
* @author grl
* @date 2019年12月16日 新建
*/
public class Order implements Delayed {
private String orderShopNum;
/**
* 1-普通活动 2-限时活动 3-拼购活动
*/
private int orderType;
private long orderCreateTime;
private long expTime;
public Order(String orderShopNum, int orderType, Date createTime) {
if (StringUtils.isNotBlank(orderShopNum)) {
this.orderShopNum = orderShopNum.trim();
}
if (createTime == null) {
this.orderCreateTime = System.currentTimeMillis();
} else {
this.orderCreateTime = createTime.getTime();
}
this.orderType = orderType;
if (orderType == 2) {
this.expTime = TimeUnit.MILLISECONDS.convert(Const.LIMIT_ACTIVITY_EXPIRATION_TIME, TimeUnit.MINUTES)
+ createTime.getTime();
}if(orderType == 3){
this.expTime = TimeUnit.MILLISECONDS.convert(Const.LIMIT_GROUP_BUY_EXPIRATION_TIME, TimeUnit.MINUTES)
+ createTime.getTime();
} else {
this.expTime = TimeUnit.MILLISECONDS.convert(Const.ORDER_PAYMENT_DEADLINE, TimeUnit.DAYS)
+ createTime.getTime();
}
}
public String getOrderShopNum() {
return orderShopNum;
}
public long getOrderCreateTime() {
return orderCreateTime;
}
public long getExpTime() {
return expTime;
}
public int getOrderType() {
return orderType;
}
@Override
public int compareTo(Delayed o) {
return Long.valueOf(this.expTime).compareTo(Long.valueOf(((Order) o).expTime));
}
@Override
public long getDelay(TimeUnit unit) {
return unit.convert(this.expTime - System.currentTimeMillis(), TimeUnit.MILLISECONDS);
}
}
/**
* 类说明
*
* @author grl
* @date 2019年12月16日 新建
*/
public class OrderCollection {
/**
* 订单管理集合
*/
private static DelayQueue<Order> orderList = new DelayQueue<Order>();
private OrderCollection() {
}
/**
* 获取订单集合
* @author grl
* @return
*/
protected static DelayQueue getOrderCollection() {
return orderList;
}
/**
* 向集合中添加订单
*
* @author grl
* @param order
* @return
*/
public static boolean add(Order order) {
boolean flag = false;
if (order != null && StringUtils.isNotBlank(order.getOrderShopNum())) {
flag = orderList.offer(order);
}
return flag;
}
/**
* 从集合中删除订单
*
* @author grl
* @param orderShopNum
* @return
*/
public static boolean remove(String orderShopNum) {
boolean flag = false;
Order thisOrder = null;
if (StringUtils.isNotBlank(orderShopNum)) {
orderShopNum = orderShopNum.trim();
for (Order order : orderList) {
String orderNum = order.getOrderShopNum();
if (orderNum.equals(orderShopNum)) {
thisOrder = order;
}
}
if (thisOrder != null) {
flag = orderList.remove(thisOrder);
}
}
return flag;
}
/**
* 获取订单的过期剩余时间
*
* @author grl
* @param orderShopNum
* @param unit
* @return -1 已经过期
*/
public static long getDelay(String orderShopNum) {
long time = -1;
if (StringUtils.isNotBlank(orderShopNum)) {
orderShopNum = orderShopNum.trim();
for (Order order : orderList) {
String orderNum = order.getOrderShopNum();
if (orderNum.equals(orderShopNum)) {
time = order.getDelay(TimeUnit.MILLISECONDS);
if(time<5000) {
time = -1;
}
}
}
}
return time;
}
}
/**
* 类说明
*
* @author grl
* @date 2019年12月16日 新建
*/
@Component
public class CancellOrder implements Runnable {
private static final Logger log = LoggerFactory.getLogger(CancellOrder.class);
@Override
public void run() {
while (true) {
try {
Order take = OrderCollection.getOrderCollection().take();
String orderShopNum = take.getOrderShopNum();
int orderType = take.getOrderType();
// 业务逻辑操作
} catch (InterruptedException e) {
e.printStackTrace();
log.error("CancellOrder DelayQueue 错误 {}", e.getMessage());
}
}
}
}
总结
以上所述是小编给大家介绍的Java实现商城订单超时取消功能网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!
来源:https://blog.csdn.net/kisslongge00/article/details/103562753


猜你喜欢
- 现象:安装失败,具体信息:Installation did not succeed.The application could not be
- bufferedReader.readLine()读到最后发生阻塞最近在做一个imageserver,需求简化后就是使用socket响应HT
- AndroidStudio打包jar最近更新androidstudio之后发现打包jar不可用了。先看下以前的方法更新后新的用法//Copy
- 有时候我们从数据库中查询出来数据之后,需要按照DataTable的某列进行分组,可以使用下面的方法实现,代码如下:using System;
- 实践过程效果代码public partial class Form1 : Form{ public Form1()
- 前言需求是上传Excel文件并读取Excel文件中的内容,根据获取的数据执行完某些业务操作后再将一些数据写回到excel中。前台使用Form
- AOP概念的引入传统的登录原理:如上图所示这是一个基本的登录原理图,但是如果我们想要在这个登录之上添加一些新的功能,比如权限校验那么我们能想
- 一、Mybatis中的延迟加载1、延迟加载背景:Mybatis中Mapper配置文件中的resultMap可以实现高级映射(使用associ
- 前一篇博文介绍了JDK logging基础知识 博文中也提到LogManager,本章主要阐述怎么完全定制化LogManager来
- Convert.ToInt32、int.Parse(Int32.Parse)、int.TryParse、(int) 四者都可以解释为将类型转
- 废话不多说了,直接给大家贴代码了,具体代码如下所述:/*** 把一个View的对象转换成bitmap*/private Bitmap get
- 目前较常用的分页实现办法有两种:1.每次翻页都修改SQL,向SQL传入相关参数去数据库实时查出该页的数据并显示。2.查出数据库某张表的全部数
- Log4j组件构成 Log4j由三个重要的组件构成:1.日志信息的优先级(Logger)2.日志信息的输出目的地(Appender
- 表单代码<!DOCTYPE html><html lang="en" xmlns="http
- 记得在学习数据结构的时候一味的想用代码实现算法,重视的是写出来的代码有一个正确的输入,然后有一个正确的输出,那么就很满足了。从网上看了许多的
- substring(参数)是java截取字符串的一个方法。它有两种传参的方式:第一种:public String substring(int
- 我们知道,在 Python 里面,如果你要运行一段 JavaScript,你可以使用execJS这种第三方库。那么在 Golang 里面,你
- application.properties有以下这几条数据方法一:@Value注解+@Component建议properties少的时候用
- 官网文档背景项目A中需要多数据源的实现,比如UserDao.getAllUserList() 需要从readonly库中读取,但是UserD
- 今天记录一下TextView的倒影效果,显示一串文字,然后在文字的下方显示出它的倒影,先上效果图:最重要的就是View中getDrawing