集群环境下如何防止定时任务重复执行?

起因 
最近做项目是遇到这样一个问题:系统需要在每天的16:00向一些符合特定条件的用户发送一份邮件,发送成功后修改掉数据库中对应数据的标志位。本来是没有问题的,但后来系统被部署到了集群环境下,导致每天会向这些用户发送多次同样的数据,遭到了客户的抱怨。 
解决 
下面来介绍一下处理这种问题的解决办法: 
1.在数据库中建立tm_job_group表

NameTypeComments
group_idnumber组id
intervalnumber时间间隔
区分定时任务的间隔
即多长时间内不可重复执行,单位分钟
remarkvarchar2(100)描述

数据如下:

group_idintervalremark
1144024小时执行一次
2601小时执行一次
31202小时执行一次

2.在数据库中建立一张tm_job表,用来存储定时任务的信息

NameTypeComments
job_idnumber定时任务的id
job_namevarchar2(100)定时任务的名称
job_groupnumber定时任务所属的组
remarkvarchar(100)备注

数据如下:

job_idjob_namejob_groupremark
1催办邮件发送Job1每天16点执行

3.建立ts_job_log表

NameTypeComments
job_log_idnumberjob的logId,自增
job_idnumber定时任务id
job_groupnumber定时任务所属的组
job_start_timedate执行时间
job_statusvarchar2(10)状态 执行情况
job_msgvarchar2(100)备注

这三张表的外键关联可以自己设定,这里就不写了。 
然后为ts_job_log表添加如下的约束:

create  unique  index   idx_ts_job_log_starttime   on  ts_job_log(job_id,decode(job_group,1,to_char(job_start_time,'yyyymmdd'),2,to_char(job_start_time,'yyyymmddhh24'),3,trunc(to_char(job_start_time,'yyyymmddhh24')/2)),TO_CHAR(JOB_START_TIME,'DD-MON-RR'))
 
 
  • 1

这个约束表示 当job_group为1时,在同一天不可以存在两个一样的job_id,当job_group为2时,在同一小时内不可存在两个相同的job_id,job_group为3时,在两个小时内不能出现同样的job_id. 
时间比较的是job_start_time的时间间隔。

在执行定时任务的操作时,先向数据表中insert一条数据,如: 
insert into ts_job_log(job_log_id,job_id,job_group,job_start_time,job_status) 
values(1,1,1,sysdate,’正常’); 
可以添加成功 
当再执行如下操作时 
insert into ts_job_log(job_log_id,job_id,job_group,job_start_time,job_status) 
values(2,1,1,sysdate,’正常’); 
会报错 
如果在代码中捕获到错误就不执行定时任务中的操作。

总结 
这种方法就是通过让数据库中的操作受到约束条件产生异常来实现的。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值