之前在公司做一个定时任务,任务本身的逻辑难度一般,但是我们生产环境是4台服务器集群的,测试环境也是2台服务器集成,那么对于JOB来说就会面临一个问题,

假如你的JOB是每天凌晨2.30跑,那么同一时间4台服务器都会去执行这个JOB,如果对同一个数据进行update操作就会发生脏读了。 处理这个问题可以用数据库的update 锁来解决, 因为我们知道update之后 会返回更新的条数  ,所以我们用一个标示状态来表示目前有台服务器在执行JOB了

如 标示用 flag表示 默认 为N 没有JOB执行   , 第一个服务器进入JOB 把这个标示给更新成 Y 那么会成功返回update条数 1 ,其他的三台机器则会update条数为0所以 if判断一下就好,然后在正常执行完和异常代码块里都还原一下 就是把 Y 改成N    代码贴上:

@Override
    public String executeMsgBoardScheduleAndRemindDisableJobByAdmin(List<BussinessDTO> list) {
        String message = " 留言板排班";
        boolean isGetLock = false;
        
        try {
            // N为目前没人执行 Y表示已经在执行 如果 N 能改为Y 证明目前没人执行。 默认执行完都会改为N
            // 将N改为Y 如果修改条数大于0说明成功, 目前没人
            int updatedCount = commSysParamService.updateParamValueByParamKey(SystemConstant.MESSAGE_SCHEDULE_QUARTZ_IS_STARTED, SystemConstant.NO, SystemConstant.YES, null);
            boolean isQuartzStarted = (updatedCount <= 0);
    
            if (isQuartzStarted) {
                message = "已在执行,无法重执行!";
                logger.info("executeMsgBoardScheduleAndRemindJob: " + message);
                return message;
            }
            else {
                isGetLock = true;
            }
            
            StopWatch watch = new StopWatch();
            watch.start();
            logger.info("executeMsgBoardScheduleAndRemindJob: 任务开始");
           //处理完等待5分钟, 防止其他服务器重复执行
            Thread.sleep(5 * 60 * 1000);
            
            watch.stop();
            logger.info("executeMsgBoardScheduleAndRemindJob: 任务完成, 执行花费时间为:" + watch.getTime());

        }
        catch (Exception e) {
            message = "执行发生异常!执行失败!请联系管理员!";
            logger.error("executeMsgBoardScheduleAndRemindDisableJob: " + message, e);
        }
        finally {
            // 所有任务执行完毕后打开开关让下次可以进入执行
            try {
                if(isGetLock) {
                    commSysParamService.updateParamValueByParamKey(SystemConstant.MESSAGE_SCHEDULE_QUARTZ_IS_STARTED, SystemConstant.YES, SystemConstant.NO, null);
                }
            }
            catch (BusinessServiceException e) {
                logger.error("executeMsgBoardScheduleAndRemindJob: 重置MESSAGE_SCHEDULE_QUARTZ_IS_STARTED 失败", e);
            }
        }

        return message;
    }

 

备注: 这个需要创建一个 配置参数表, id    key  value  足以