up:: SpringCloud之CRON表达式

说明:


正式开发使用定时任务批量关闭过期订单

添加方法查询过期了的订单(过期时间为1天)

@Override
public List<Order> getUnpaidOrders() {
    Date curTime = new Date();
    Date endTime = DateUtils.addDays(curTime, -1);
    Date begTime = DateUtils.addMinutes(endTime, -5);
    List<Order> unpaidOrders = orderMapper.selectUnpaidOrders(begTime, endTime);
    return unpaidOrders;
}

说明:

实现mapper层查询过期订单

mapper.xml文件实现sql语句

<select id="selectUnpaidOrders" resultMap="BaseResultMap">
  select
  <include refid="Base_Column_List"/>
  from imooc_mall_order where
  create_time between #{begTime} and #{endTime}
  and order_status = 10
</select>

开发完MVC,我们就要实现定时任务的方法了(重要!!!)

package com.imooc.cloud.mall.practice.cartorder.config;
 
import com.imooc.cloud.mall.practice.cartorder.model.pojo.Order;
import com.imooc.cloud.mall.practice.cartorder.service.OrderService;
import com.imooc.cloud.mall.practice.common.exception.GlobalExceptionHandler;
import java.util.List;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
 
/**
 * 描述:     定时任务类
 */
@Component
public class JobConfiguration {
 
    @Autowired
    OrderService orderService;
 
    @Autowired
    RedissonClient redissonClient;
 
 
    @Scheduled(cron = "0 0/5 * * * ?")
    public void cancelUnpaidOrders() {
        RLock redissonLock = redissonClient.getLock("redissonLock");
        boolean b = redissonLock.tryLock();
        if (b) {
            try {
                System.out.println("redisson锁+1");
                List<Order> unpaidOrders = orderService.getUnpaidOrders();
                for (int i = 0; i < unpaidOrders.size(); i++) {
                    Order order = unpaidOrders.get(i);
                    orderService.cancel(order.getOrderNo(), true);
                }
            } finally {
                redissonLock.unlock();
                System.out.println("redisson锁已释放");
            }
        } else {
            System.out.println("redisson锁未获取到");
        }
    }
 
}

说明:

Lock()方法:

  lock()方法是一个无条件的锁,与synchronize意思差不多,直接去获取锁。成功了就ok了,失败了就进入阻塞等待了。不同的是lock锁是可重入锁。

另一个方法 tryLock()方法:

  当获取锁时,只有当该锁资源没有被其他线程持有时才可以获取到,成功获取到锁资源之后,会立即返回true

  当获取锁时,如果有其他的线程正在持有该锁,无可用锁资源,则会立即返回false!这时候当前线程不用阻塞等待,可以先去做其他事情;

  如果为这个方法加上timeout参数,则会在等待timeout的时间之后,才会返回false,或者在获取到锁之后返回true。

相当于操作系统中的互斥信号量!!!

重点在于时间不是同时的,同个空间不同时间可以共用,时间是运动的,所以可以解决掉不需要每个开辟一个空间。。。


redisson实现分布式锁

引入依赖

<!-- redisson -->
<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson</artifactId>
    <version>3.11.1</version>
</dependency>

配置redisson

package com.imooc.cloud.mall.practice.cartorder.config;
 
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
 
/**
 * 描述:     TODO
 */
@Configuration
public class RedissonConfig {
    @Bean
    public RedissonClient config() {
        Config config = new Config();
        config.useSingleServer().setAddress("redis://127.0.0.1:6379");
        RedissonClient redisson = Redisson.create(config);
        return redisson;
    }
}

说明:

第一次介绍【@Configuration注解】和【@Bean注解】是在【JavaConfig-对象实例化】;如有需要,可以先去快速参考这篇博客内容;

推荐阅读: Redisson 分布式锁的使用