有关定时任务的分布式调度的一致性失效问题

问题描述

由于业务需求,公司使用 sqlserver 数据库。而且 xxl-job 分别被部署在了两天服务器上。导致了有时会出现同一个定时任务被重复执行的情况出现。

推荐阅读:xxl-job 使用 sqlserver数据库后,报警邮件失效

官方文档描述

  • 一致性:“调度中心”通过DB锁保证集群分布式调度的一致性, 一次任务调度只会触发一次执行;

原因分析

定时任务被分别部署在【服务器 A、B】上,定时任务的数据库位于【服务器 C】上。而同一个定时任务被重复执行,说明分布式调度的【一致性】失效。

考虑到官方的 mysql 版本是通过 DB 锁保证的一致性,有可能是 sqlserver 不支持 mysql 的语法。

通过核心类【XxlJobScheduler】进入到定时任务的执行类【JobScheduleHelper】中,便能看到 mysql 的加锁语句。

  • 具体实现见下方:

XxlJobScheduler

  • JobScheduleHelper.getInstance().start():该方法是定时任务的执行
public class XxlJobScheduler  {
    private static final Logger logger = LoggerFactory.getLogger(XxlJobScheduler.class);
    public void init() throws Exception {
       JobScheduleHelper.getInstance().start();
    }
}

JobScheduleHelper

改造前语句

在执行定时任务时,会通过 select xxx for update 对其进行加锁,而此 sql 语句在 sqlserver 中并不适用。

preparedStatement = conn.prepareStatement(  "select * from xxl_job_lock where lock_name = 'schedule_lock' for update" );

改造后语句

 SELECT * FROM xxl_job_lock WITH (TABLOCKX) WHERE lock_name = 'schedule_lock' 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值