业务说明

说明:如果订单提交之后如果30分钟没有完成付款,则将订单状态改为6.表示订单交易关闭.
问题:如何实现每个订单30分钟超时呀???

思路1: 利用数据库的计时的函数每当order入库之后,可以添加一个函数30分钟之后修改状态.
该方法不友好, 100万的订单刚刚入库. 100万个监听的事件.
思路2: 利用消息队列的方式实现 redis 开启线程向redis中存储数据之后设定超时时间.当key一旦失效则修改数据库状态.
Redis主要做缓存使用. 但是不合适.
思路3:
开启单独的一个线程(异步),每隔1分钟查询一次数据库,修改超时的订单处理即可.

Quartz介绍

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

java 订单系统支付回调失败主动查询 java订单超时怎么处理_java 订单系统支付回调失败主动查询


组件说明:

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

导入jar包

<!--添加Quartz的支持 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-quartz</artifactId>
        </dependency>

编辑配置类

package com.jt.conf;

import com.jt.quartz.OrderQuartz;
import org.quartz.CronScheduleBuilder;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@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();
	}
}

编辑定时任务

package com.jt.quartz;

import java.util.Calendar;
import java.util.Date;

import com.jt.mapper.OrderMapper;
import com.jt.pojo.Order;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.quartz.QuartzJobBean;
import org.springframework.stereotype.Component;
import org.springframework.transaction.CannotCreateTransactionException;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.dubbo.config.annotation.Reference;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;


//准备订单定时任务
@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("定时任务执行");
	}
}