超时订单

阐明:电商我的项目中,如果订单提交之后如果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。

组件阐明:

  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>

编辑配置类

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

编辑定时工作

//筹备订单定时工作@Componentpublic 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("定时工作执行");    }}