文章目录
设置定时任务
编写定时任务配置
package com.beyond.config;
import com.beyond.utils.DateUtil;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@Component
public class OrderJob {
@Scheduled(cron = "0/3 * * * * ?")
public void autoCloseOrder(){
System.out.println("执行定时任务, 当前时间为: "
+ DateUtil.getCurrentDateString(DateUtil.DATETIME_PATTERN));
}
}
开启定时任务
效果展示
设置订单超时
编写超时配置并开启 OrderJob.java
package com.beyond.config;
import com.beyond.service.OrderService;
import com.beyond.utils.DateUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@Component
public class OrderJob {
@Autowired
private OrderService orderService;
@Scheduled(cron = "* * 0-23 * * ?") // 每一天执行一次
public void autoCloseOrder(){
orderService.closeOrder();
System.out.println("执行定时任务, 当前时间为: "
+ DateUtil.getCurrentDateString(DateUtil.DATETIME_PATTERN));
}
}
编写完善 orderService
/**
* 关闭超时未支付的订单
*/
public void closeOrder();
编写完善 orderServiceImpl
@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());
if (days >= 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);
}
分析:
使用如上的定时任务关闭超期未支付的订单, 会存在的弊端
-
会有时间差, 会导致程序不严谨.
比如: 10:20 下单, 11:00 检查不足一小时, 12:00 检查, 超过了1小时多余20分钟 -
不支持集群
单机没毛病, 使用集群后, 就会有多个定时任务
解决方案: 只使用一台计算机节点, 单独用来运行所有的定时任务 -
最大的弊端
会对数据库全表搜索, 极其影响数据库性能,
因为我们写的是 select * from order where orderStatus = 10 ;
所以, 这样的定时任务只是适用于小型轻量级项目, 传统项目.
后续会涉及到消息队列 : MQ -> RabbitMQ, RocketMQ, Kafka, ZeroMQ…
即启动 延时任务(队列)