你还在轮询数据库修改订单状态吗

一、背景

    多数电商都会遇到限时订单处理。例如到付款订单30分钟变为订单关闭状态。七天自动收货等。

二、解决方案

   1、轮询数据库:实现一个定时器,每隔一段时间去检查一遍数据库里的所有订单,查看其状态是否是未支付并且已经到期。并修改这些数据的状态为已过期。

    优点:方法简单,容易实现

    缺点:订单状态处理不及时,轮询数据库的次数中可能很多都并没有修改订单(做的无用功),数据库频繁多次被连接浪费数据库资源开销。

     因此以上方式实际开发中基本不予采用。开发中真正实现限时订单采用以下两种方案:

    2、DelayQueue,延时队列 - java自带方法

    1)、用户下单,保存订单到数据库的同时,将该订单以及订单的过期时间推入DelayQueue

    (2)、启动一个检查订单到期的线程,该线程使用delayQueue的take()方法获取到期订单,该方法为阻塞方法,如果当前没有到期订单,该方法会一直阻塞等待,直到获取到订单后继续往下执行。

    (3)、当take()获取到一个到期订单后,该线程按获取到的订单的id去数据库查询订单并去检查订单状态,如果为未支付,则将状态修改为已过期

        2.1、SpringBoot框架下代码实现

      延时队列实体Bean

你还在轮询数据库修改订单状态吗

你还在轮询数据库修改订单状态吗

 延时订单业务处理接口

你还在轮询数据库修改订单状态吗

  延时订单业务处理实现类

你还在轮询数据库修改订单状态吗

你还在轮询数据库修改订单状态吗

     如果我们只实现了以上的代码,会存在一个很严重的问题,因为延时订单是存在DelayQueue中的,而DelayQueue是存在内存中的,那么当系   统重启后,DelayQueue中的数据就被清空了,因此当系统重新启动的时候,需要在订单的实现类中去做一个检索数据库订单的操作,将已过期未支付的设置为已过期,将未过期未支付的重新推入DelayQueue队列中。代码如下:

你还在轮询数据库修改订单状态吗

 @PostConstruct  系统启动时执行