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 分布式锁的使用