电商项目实战(架构五)—— SpringTask实现定时任务
一、前言
定时任务在生活中处处体现,例如早上起不来的时候,需要定个闹钟来叫一下自己,那么在程序中哪些场景会用到定时任务呢?订单生成之后要有一个支付的过程,在支付的时候,一看到支付金额,突然觉得太多了,就不支付了,我也不取消订单,就吊着,这样所买商品的库存一直处于锁定状态,少量的还好,要是锁它个几千几万的,别人还买不买了,这个时候,定时取消未支付订单,就很好的解决了这个问题。
二、框架
1、SpringTask
SpringTask是Spring自主研发的轻量级的定时任务工具,不需要引入其他依赖
2、Cron表达式
Cron表达式是一个字符串,其语法格式为:Seconds Minutes Hours DayofMonth Month DayofWeek
Cron格式中特殊字符有:
字符 |
作用 | 举例 |
,(逗号) | 列出枚举值 |
在Minutes域使用5,10,表示在5分和10分的时候各触发一次 |
-(短横线) | 表示触发范围 |
在Minutes域使用5-10,表示在5到10分内,每分钟触发一次 |
*(星号) | 表示匹配任意值 |
在Minutes域使用*,表示每分钟都会触发一次 |
/(左斜杠) |
表示开始触发时间 和每个固定时间触发 |
在Minutes域使用5/10,表示从5分开始触发一次后,每隔 10分钟触发一次 |
?(问号) |
只在DayofMonth和 DayofWeek中匹配任意值 |
在DayofMonth域使用?,表示每天都触发一次 |
#(井号) |
只在DayofMonth中使用 表示第几个星期几 |
在DayofMonth域中使用1#3,表示每月的第三个星期日 触发一次 |
L(大写L) | 表示最后 |
在DayofWeek域使用5L,表示在最后一个星期四触发 |
|
Cron语法中元素说明
时间元素 | 可出现的字符 |
有效数值范围 |
Seconds | , - * / |
0-59 |
Minutes |
, - * / | 0-59 |
Hours |
, - * / | 0-59 |
DayofMonth |
, - * / ? L W | 0-31 |
Month |
, - * / | 1-12 |
DayofWeek |
, - * / ? L # | 1-7 或 SUN-SAT |
三、业务场景
· 用户对某商品进行下单操作
· 系统需要根据用户购买的商品信息生成订单并锁定商品的库存
· 系统设定用户60分钟不支付,自动取消订单
· 开启一个定时任务,每隔10分钟进行一次扫描,如果有超时未支付订单,就将订单取消并释放库存商品
四、整合SpringTask
1、在config包下新建启动SpringTask启动类SpringTaskConfig
package com.zzb.test.admin.config; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.annotation.EnableScheduling; /** * 定时任务配置类 * Created by zzb on 2019/11/26 12:17 */ @Configuration @EnableScheduling public class SpringTaskConfig { }
2、在component包下新建SpringTask配置类OrderTimeOutCancelTask
package com.zzb.test.admin.common; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; /** * 定时任务 订单超时自动取消并释放库存商品 * Created by zzb on 2019/11/26 11:07 */ @Component public class OrderTimeOutCancelTask { private static final Logger logger = LoggerFactory.getLogger(OrderTimeOutCancelTask.class); // TODO: 2019/11/26 Seconds Minutes Hours DayofMonth Month DayofWeek @Scheduled(cron = "0 0/10 * ? * ?") public void cancelTimeOutOrder(){ // TODO: 2019/11/26 从零点开始,每隔10分钟扫描一次,查询未支付订单 logger.info("取消订单,并释放库存商品"); } }
五、测试
启动项目,等待10分钟查看日志
项目github地址:https://github.com/18372561381/shoptest