任务异步执行
// 定时任务设计思路:
// 1、先把任务修改为执行中即可结束此方法,同时异步调用任务执行方法
// 2、定时任务扫描执行中的任务,遍历任务执行
private ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 1, 0, TimeUnit.SECONDS, new LinkedBlockingQueue(1), new ThreadPoolExecutor.DiscardOldestPolicy());
// 定时任务每隔30秒调用一次
@Scheduled(cron="0/30 * * * * ?")
public void taskHandle() {
// 由于定时调度默认是单线程的,这里可以快速执行完成本方法
threadPoolExecutor.submit(() -> {
try {
// 需要根据状态查询数据,这里给之前的方法预留事务事务的时间
Thread.sleep(1000);
List list = new ArrayList();
// 可以根据需要并发处理任务
list.parallelStream().forEach(a -> prepareHandle());
} catch (Throwable e) {
log.error("", e);
}
});
}
// 预调用方法处理
private void prepareHandle() {
// 获取锁
RLock rLock = new RedissonLock();
if (rLock.tryLock()) {
try {
// 执行过程会再次验证任务状态,这里给之前的方法预留事务提交
Thread.sleep(1000);
concreteMethod();
} catch (Throwable e) {
log.error("", e);
} finally {
rLock.unlock();
}
}
}
// 本方法设置为事务方法,以便于本方法的内容同时成功、失败
@Transactional(rollbackFor = Throwable.class)
public void concreteMethod() {
// 再次获取可重入锁
RLock lock = new RedissonLock();
if (lock.tryLock()) {
try {
// 1、判断是否在执行中,否则在这里直接结束执行
// 2、执行处理逻辑
// 3、无报错的情况下即为处理成功,执行成功流程
} catch (Throwable e) {
log.error("", e);
// 4、有异常的情况下,执行异常处理流程
} finally {
lock.unlock();
}
}
}