Java实现商城订单超时取消功能

 更新时间:2019年12月17日 11:50:00   作者:长路漫漫~Gavin  
大多数的B2C商城项目都会有限时活动,当用户下单后都会有支付超时时间,当订单超时后订单的状态就会自动变成已取消 ,这个功能的实现有很多种方法,本文的实现方法适合大多数比较小的商城使用。具体实现方式可以跟随小编一起看看吧

 大多数的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实现商城订单超时取消功能,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

相关文章

  • 通过实例解析Java不可变对象原理

    通过实例解析Java不可变对象原理

    这篇文章主要介绍了通过实例解析Java不可变对象原理,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-10-10
  • Spring Security6 最新版配置及实现动态权限管理

    Spring Security6 最新版配置及实现动态权限管理

    Spring Security 在最近几个版本中配置的写法都有一些变化,很多常见的方法都废弃了,并且将在未来的 Spring Security7 中移除,因此又补充了一些新的内容,重新发一下,供各位使用 Spring Security 的小伙伴们参考,需要的朋友可以参考下
    2024-03-03
  • springboot html调用js无效400问题及解决

    springboot html调用js无效400问题及解决

    这篇文章主要介绍了springboot html调用js无效400的问题及解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-03-03
  • 一文看懂springboot实现短信服务功能

    一文看懂springboot实现短信服务功能

    项目中的短信服务基本上上都会用到,简单的注册验证码,消息通知等等都会用到。这篇文章主要介绍了springboot 实现短信服务功能,需要的朋友可以参考下
    2019-10-10
  • 零基础入门学习——Spring Boot注解(一)

    零基础入门学习——Spring Boot注解(一)

    这篇文章主要介绍了Spring Boot注解学习(一)要点,非常不错,具有参考借鉴价值,需要的朋友参考下吧
    2017-05-05
  • MyBatis typeHandler接口的定义和使用

    MyBatis typeHandler接口的定义和使用

    TypeHandler被称作类型处理器,MyBatis在设置预处理语句中的参数或从结果集中取出一个值时,都会用类型处理器将Java对象转化为数据库支持的类型或者将获取到数据库值以合适的方式转换成Java类型,感兴趣的同学可以参考下文
    2023-05-05
  • JavaSE API实现生成随机数的2种方法(Random类和Math类的Random方法)

    JavaSE API实现生成随机数的2种方法(Random类和Math类的Random方法)

    本文主要介绍了JavaSE API实现生成随机数的2种方法,主要包括Random类和Math类的random方法都可以用来生成随机数,具有一定的参考价值,感兴趣的可以了解一下
    2023-10-10
  • Java数组与二维数组及替换空格实战真题讲解

    Java数组与二维数组及替换空格实战真题讲解

    数组对于每一门编程语言来说都是重要的数据结构之一,当然不同语言对数组的实现及处理也不尽相同。Java 语言中提供的数组是用来存储固定大小的同类型元素,这篇文章主要介绍了Java数组与二维数组及替换空格实战真题讲解
    2022-07-07
  • 利用Java8 Optional类优雅如何地解决空指针问题

    利用Java8 Optional类优雅如何地解决空指针问题

    这篇文章主要给大家介绍了关于如何利用Java8 Optional类优雅解决空指针问题的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-11-11
  • Spring的Xml和JavaConfig 扩展哪个好用

    Spring的Xml和JavaConfig 扩展哪个好用

    今天给大家介绍基于注解的Spring扩展,Spring的Xml和JavaConfig 扩展的配置方法,关于Spring的Xml和JavaConfig 扩展你会选哪个呢,带着这个问题一起通过本文学习下吧
    2021-05-05

最新评论