Quartz framework realizes timing service

Overtime order

Note: in the e-commerce project, if the payment is not completed within 30 minutes after the order is submitted, change the order status from 1 (pending payment) to 6 (transaction failed) Indicates that the order transaction is closed
Question: how to achieve 30 minute timeout for each order?

Idea 1: using the timing function of the database, you can add a function to modify the status 30 minutes after order is put into storage
This method is not friendly. 1 million orders have just been put into storage One million listening events It will cause the database to crash due to listening

Idea 2: use message queue to realize redis. Set timeout after starting thread to store data in redis Once the key fails, modify the database status
Redis is mainly used for caching But it's not appropriate

Idea 3: start a separate thread (asynchronous), query the database every 1 minute, and modify the overtime order processing

Introduction to Quartz framework

java's native timer can also enable a separate thread to implement timed tasks, but there are some defects. Now Quartz is a more commonly used form

Quartz is another open source project of OpenSymphony open source organization in the field of Job scheduling. It can be combined with J2EE and J2SE applications or used alone. Quartz can be used to create simple or complex programs that run ten, a hundred, or even tens of thousands of jobs. Jobs can be made into standard Java components or EJBs. The latest version of quartz is Quartz 2.3.2.

Component description:

  1. Job is a user - defined task
  2. jobDetail is the tool API responsible for encapsulating tasks If the task needs to be executed, it must be encapsulated by jobDetail
  3. Scheduler: it is responsible for time monitoring. When the execution time of the task arrives, it will be handed over to the trigger for processing
  4. Trigger: when receiving the command from the scheduler, start a new thread to execute the job

Quartz implementation

Import jar package

<!--add to Quartz Support of -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-quartz</artifactId>
</dependency>

Edit configuration class

@Configuration
public class OrderQuartzConfig {

    /**
     * Idea Description:
     *     Issues to consider if scheduled tasks need to be performed
     *     1.How often is the task performed Once a minute
     *     2.What should a scheduled task perform
     */
    //Define task details
    @Bean
    public JobDetail orderjobDetail() {
        //Specify the name of the job and the persistent save task
        return JobBuilder
                .newJob(OrderQuartz.class)        //1. Define the tasks to be performed
                .withIdentity("orderQuartz")    //2. Task assignment name
                .storeDurably()
                .build();
    }
    //Define trigger
    @Bean
    public Trigger orderTrigger() {
        /*SimpleScheduleBuilder builder = SimpleScheduleBuilder.simpleSchedule()
                .withIntervalInMinutes(1)    //Define time period
                .repeatForever();*/
        CronScheduleBuilder scheduleBuilder 
            = CronScheduleBuilder.cronSchedule("0 0/1 * * * ?");
        return TriggerBuilder
                .newTrigger()
                .forJob(orderjobDetail())    //Tasks performed
                .withIdentity("orderQuartz")    //Name of the task
                .withSchedule(scheduleBuilder).build();
    }
} 

Edit scheduled task

//Prepare order timing task
@Component
public class OrderQuartz extends QuartzJobBean{

    @Autowired
    private OrderMapper orderMapper;

    /**
     * If the user does not complete the payment within 30 minutes, change the status of the order from 1 to 6
     * Basis of condition judgment: now() - creation time > 30 minutes < = = > 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. Use the java tool API to complete the calculation
        Calendar calendar = Calendar.getInstance();  //Get current time
        calendar.add(Calendar.MINUTE,-30);
        Date timeOut = calendar.getTime();    //Get timeout

        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("Scheduled task execution");
    }
}

Tags: Quartz

Posted by adhi_nugraha on Sun, 15 May 2022 16:45:48 +0300