Spring Schedule定时框架

Spring Schedule定时框架学习笔记,通过该框架可以实现定时任务,按照指定间隔执行指定代码。

Spring Schedule简介

什么是Spring Schedule?

作业调度,如定时任务。

Spring Schedule的实现流程

定时关单功能实现流程
  1. 编辑spring.xml配置文件,增加如下内容:
    //IDEA中会出现关联提示,选择结尾是task的driven(观察顶部是否新增了声明,如果有则无需执行第二步)
    <task:annotation-driven/>
    

2.(若IDE自动添加了声明,则无需手动更改)新增task相关声明

xmlns:task="http://www.springframework.org/schema/task"
http://www.springframework.org/schema/task
http://ww.springframework.org/schema/task/spring-task.xsd
  1. 新建task包,创建CloseOrderTask.java类
    //类的上一行增加@Component注解
    //该方法适合单服务器,不适合集群服务器
    @Scheduled(cron="0 */1 * * * ?")//每1分钟执行一次(每个1分钟的整数倍)
    public void closeOrderTaskV1(){
      int hour = Integer.parseInt(PropertiesUtil.getProperty("close.order"));
      iOrderService.closeOrder(hour);
    }
    
  2. 打断点进行测试。完成
Spring Schedule+Redis分布式锁构建分布式任务调度实现流程
  1. 编辑spring.xml配置文件,增加如下内容:
    //IDEA中会出现关联提示,选择结尾是task的driven(观察顶部是否新增了声明,如果有则无需执行第二步)
    <task:annotation-driven/>
    

2.(若IDE自动添加了声明,则无需手动更改)新增task相关声明

xmlns:task="http://www.springframework.org/schema/task"
http://www.springframework.org/schema/task
http://ww.springframework.org/schema/task/spring-task.xsd
  1. 新建task包,创建CloseOrderTask.java类(该方法有做防死锁问题)
    @Scheduled(cron="0 */1 * * * ?")
    public void closeOrderTaskV2(){
      log.info("关闭订单定时任务启动");
      long lockTimeout = Long.parseLong(PropertiesUtil.getProperty("lock.timeout","5000"));
      Long setnxResult = RedisShardedPoolUtil.setnx(Const.REDIS_LOCK_CLOSE_ORDER_TASK_LOCK,String.valueOf(System.currentTimeMillis()+longTimeout));
      if(setnxResult != null&&setnxResult.intValue()==1){
        //表示设置成功,获取到锁
        closeOrder(Const.REDIS_LOCK.CLOSE_ORDER_TASK_LOCK);
      }else{
        //防止死锁
        String oldResult = RedisShardedPoolUtil.get(Const.REDIS_LOCK_CLOSE_ORDER_TASK_LOCK);
        if(oldResult==null||(oldResult!=null&&System.currentTimeMillis()>oldResult)){
          String newResult = RedisShardedPoolUtil.getset(Const.REDIS_LOCK_CLOSE_ORDER_TASK_LOCK,String.valueOf(System.currentTimeMillis()+longTimeout));
          if(newResult==null||StringUtils.equals(newResult,oldResult)){
            closeOrder(Const.REDIS_LOCK.CLOSE_ORDER_TASK_LOCK);
          }else{
            log.info("没有获得分布式锁:{}",Const.REDIS_LOCK.CLOSE_ORDER_TASK_LOCK);
          }
        }else{
          log.info("没有获得分布式锁:{}",Const.REDIS_LOCK.CLOSE_ORDER_TASK_LOCK);
        }
      }
      log.info("关闭订单定时任务结束");
    }
    
    private void closeOrder(String lockName){
      RedisShardedPoolUtil.expire(locakName,5);//有效期5秒,防止死锁
      int hour = Integer.parseInt(PropertiesUtil.getProperty("close.order"));
      iOrderService.closeOrder(hour);
      RedisShardedPoolUtil.del(Const.REDIS_LOCK.CLOSE_ORDER_TASK_LOCK);
    }
    
  2. 打断点进行测试。完成

Spring Schedule相关知识

定时任务注解
注解说明例子
@Scheduled放在方法的上一行,表明该方法是定时任务,会按照设定的时间自动运行@Scheduled(cron=“0 */1 * * * ?”)
常用cron表达式介绍
表达式说明
0 0 0 * * ?每天0点一次
0 0 23 * * ?每天23点一次
0 */1 * * * ?每1分钟(每个1分钟的整数倍)
0 0 */6 * * ?每6小时(每个6小时的整数倍)
0 0 */1 * * ?每1小时(每个1小时的整数倍)
Cron生成器

通过Cron生成自定义的定时器

MySQL行锁表锁

使用“FOR UPDATE”代表为此次SQL语句增加事务。如果有明确的where,则是行锁。如果是不明确的where,则是表锁。

Redis分布式锁相关命令
Redis命令说明
setnxnot exists的缩写
getset先get再set,获取旧的值设置新的值
expire设置键的有效期
del删除
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值