Quartz框架实现定时业务

超时订单

说明:电商项目中,如果订单提交之后如果30分钟没有完成付款,则将订单状态由1(待付款)改为6(交易失败).表示订单交易关闭.
问题:如何实现每个订单30分钟超时?

思路1: 利用数据库的计时的函数每当order入库之后,可以添加一个函数30分钟之后修改状态.
该方法不友好, 100万的订单刚刚入库. 100万个监听的事件.会使数据库因为监听而崩溃.

思路2: 利用消息队列的方式实现 redis 开启线程向redis中存储数据之后设定超时时间.当key一旦失效则修改数据库状态.
Redis主要做缓存使用. 但是不合适.

思路3:开启单独的一个线程(异步),每隔1分钟查询一次数据库,修改超时的订单处理即可.

Quartz框架介绍

java原生的timer也可以实现开启单独线程实现定时任务,但是有一些缺陷,现在这个Quartz是比较常用的形式.

Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,它可以与J2EE与J2SE应用程序相结合也可以单独使用。Quartz可以用来创建简单或为运行十个,百个,甚至是好几万个Jobs这样复杂的程序。Jobs可以做成标准的Java组件或 EJBs。Quartz的最新版本为Quartz 2.3.2。

image

组件说明:

  1. Job 是用户自定义的任务.
  2. JobDetail 负责封装任务的工具API.如果任务需要被执行,则必须经过jobDetail封装.
  3. Schedular调度器: 负责时间监控,当任务的执行时间一到则交给触发器处理
  4. Trigger触发器: 当接收到调度器的命令则开启新的线程执行job…

Quartz实现

导入jar包
<!--添加Quartz的支持 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
编辑配置类
@Configuration
public class OrderQuartzConfig {

    /**
     * 思想说明:
     *     如果需要执行定时任务需要考虑的问题
     *     1.任务多久执行一次.  1分钟执行一次
     *     2.定时任务应该执行什么
     */
    //定义任务详情
    @Bean
    public JobDetail orderjobDetail() {
        //指定job的名称和持久化保存任务
        return JobBuilder
                .newJob(OrderQuartz.class)        //1.定义执行的任务
                .withIdentity("orderQuartz")    //2.任务指定名称
                .storeDurably()
                .build();
    }
    //定义触发器
    @Bean
    public Trigger orderTrigger() {
        /*SimpleScheduleBuilder builder = SimpleScheduleBuilder.simpleSchedule()
                .withIntervalInMinutes(1)    //定义时间周期
                .repeatForever();*/
        CronScheduleBuilder scheduleBuilder 
            = CronScheduleBuilder.cronSchedule("0 0/1 * * * ?");
        return TriggerBuilder
                .newTrigger()
                .forJob(orderjobDetail())    //执行的任务
                .withIdentity("orderQuartz")    //任务的名称
                .withSchedule(scheduleBuilder).build();
    }
} 
编辑定时任务
//准备订单定时任务
@Component
public class OrderQuartz extends QuartzJobBean{

    @Autowired
    private OrderMapper orderMapper;

    /**
     * 如果用户30分钟之内没有完成支付,则将订单的状态status由1改为6.
     * 条件判断的依据:  now()-创建时间 > 30分钟   <==>  created < now()-30
     *
     * sql: update tb_order set status=6,updated=#{updated} where status=1 and created< #{timeOut}
     * @param context
     * @throws JobExecutionException
     */
    @Override
    @Transactional
    protected void executeInternal(JobExecutionContext context) throws JobExecutionException {

        //1.利用java工具API完成计算
        Calendar calendar = Calendar.getInstance();  //获取当前的时间
        calendar.add(Calendar.MINUTE,-30);
        Date timeOut = calendar.getTime();    //获取超时时间

        Order order = new Order();
        order.setStatus(6);
        //order.setUpdated(new Date());
        UpdateWrapper<Order> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("status", "1").lt("created",timeOut);
        orderMapper.update(order, updateWrapper);
        System.out.println("定时任务执行");
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值