定时任务(持续更新)

讲解目录:

1.讲解定时任务的使用

2.以具体的例子实现:使用定时关闭超期(具体期限自己决定)未支付订单

3.讲解定时任务的弊端

4.定时任务的优化方案

================================================================

在电商系统中一般情况商品在半小时(可更改)之内不结算,就会修改成订单关闭状态:

那么 我们使用 springboot的 @Scheduled 来完成 定时任务,

1.首先创建一个类 OrderJob :【DateUtil 是自定义的】

@Component
public class OrderJob {

    // 表达式网站:http://cron.qqe2.com/
      @Scheduled(cron ="0/3 * * * * ? " )
       public void autoCloseOrder(){
          System.out.println("执行定时任务,当前时间为:"+ DateUtil.getCurrentDateString(DateUtil.DATETIME_PATTERN));
      }
}

=============================================

0/3 * * * * ? 是你想要定时的表达式:这个是每隔3秒就执行,

2.我们在浏览器上访问:http://cron.qqe2.com/:

首先 先选择几秒:

然后点击 反解析到UI

Cron表达式就会生成:将其拷贝到 @Scheduled(cron ="表达式",

3.我们需要在 Application起点类上 添加一个注解:

4.这样就可以启动了:【测试结果】

=======================================================================

测试已经完成,我们该说说订单超时管理了:

1.首先写关闭订单的impl方法:

@Transactional(propagation = Propagation.REQUIRED)
@Override
public void closeOrder() {

    // 查询所有未付款订单,判断时间是否超时(1天),超时则关闭交易
    OrderStatus queryOrder = new OrderStatus();
    queryOrder.setOrderStatus(OrderStatusEnum.WAIT_PAY.type);
    List<OrderStatus> list = orderStatusMapper.select(queryOrder);
    for (OrderStatus os : list) {
        // 获得订单创建时间
        Date createdTime = os.getCreatedTime();
        // 和当前时间进行对比
        int days = DateUtil.daysBetween(createdTime, new Date()); //DateUtil 是自定义的
        if (days >= 1) {
            // 超过1天,关闭订单
            doCloseOrder(os.getOrderId());
        }
    }
}

@Transactional(propagation = Propagation.REQUIRED)
void doCloseOrder(String orderId) {
    OrderStatus close = new OrderStatus();
    close.setOrderId(orderId);
    close.setOrderStatus(OrderStatusEnum.CLOSE.type);
    close.setCloseTime(new Date());
    orderStatusMapper.updateByPrimaryKeySelective(close);
}

===========================================================

2.编写OrderJob类:

@Component
public class OrderJob {


    @Autowired
    private OrderService orderService;


    // 表达式网站:http://cron.qqe2.com/
      @Scheduled(cron ="0/3 * * * * ? " )
       public void autoCloseOrder(){
          orderService.closeOrder();
          System.out.println("执行定时任务,当前时间为:"+ DateUtil.getCurrentDateString(DateUtil.DATETIME_PATTERN));
      }
}

结果:

第二个创建时间是后来改的

测试成功

===========================================================================

弊端:

1.会有时间差,导致程序不严谨

【以1小时为例:10:01下单,11:00检查,超时不足1小时,12:00检查,超时1小时多余59分钟(已经远超1小时了)】

2.不支持集群:

       单机没问题,使用集群后,就会有多个定时任务

       解决方案:只使用一台计算机节点,单独用来运行所有的定时任务【把项目中的所有的定时任务,分离出来,部署到某个特定的子项目】

3.会对数据库全表搜索,极其影响数据库性能:select * from order where orderStatus="10"(10意味着:待支付)

定时任务:仅仅使用于小型轻量级项目,传统项目

大型项目使用:消息队列:MQ->RabbitMQ,RocketMQ,Kafka等等(后续会使用)

发布了55 篇原创文章 · 获赞 5 · 访问量 6061

猜你喜欢

转载自blog.csdn.net/weixin_42528855/article/details/103594715
今日推荐