mysql單表控制服務器集羣job重複執行

項目中有用到quartz定時任務處理某一業務,但生產環境上是Tomcat集羣,爲了控制job重複執行,設計了一種處理方案,記錄一下。
1.首先在數據庫中新建一張表:
– 創建表
drop table if exists config_log_quartz;
create table config_log_quartz(
id_key varchar(128) not null comment ’ 主鍵id’,
target_type varchar(32) comment ‘加鎖目標類型’,
target_id varchar(32) comment ‘加鎖目標ID值’,
lock_date TIMESTAMP comment ‘加鎖時間’,
expire_date TIMESTAMP comment ‘鎖過期時間’,
created_by varchar(32) comment ‘創建人’,
created_date TIMESTAMP comment ‘創建時間’,
updated_by varchar(32) comment ‘更新人’,
updated_date TIMESTAMP comment ‘更新時間’
) comment=‘對象鎖記錄表’;

2.創建存儲過程對上表進行操作

drop procedure if exists myTest.proc_dm_lock;
create PROCEDURE myTest.proc_dm_lock(
IN p_target_type VARCHAR(32),
IN p_target_id VARCHAR(32),
IN p_lock_mins NUMERIC,
OUT p_expire_date TIMESTAMP
)
BEGIN
set @v_lock_date = SYSDATE();
set @v_type_count = 0;
set @v_lock_mins = P_lock_mins;
set @p_expire_date = null;
set p_expire_date := NULL;
IF p_lock_mins is null or p_lock_mins <= 0 THEN
set @v_lock_mins := 30;
end if;
set @v_expire_date := DATE_ADD(@v_lock_date,INTERVAL @v_lock_mins MINUTE);
UPDATE config_log_quartz l
SET l.lock_date = @v_lock_date,
l.expire_date = @v_expire_date,
l.updated_by = ‘sys’,
l.updated_date = SYSDATE()
where l.expire_date < SYSDATE()
and l.target_id = p_target_id
and l.target_type = p_target_type;
if ROW_COUNT()>0 THEN
set p_expire_date := @v_expire_date;
else
begin
select count(1)
into @v_type_count
from config_log_quartz sbq
where sbq.target_type = p_target_type
and sbq.target_id = p_target_id;
if @v_type_count = 0 then
insert into config_log_quartz(id_key,target_type,target_id,lock_date,expire_date,created_by,created_date,updated_by,updated_date)
values(UUID(),p_target_type,p_target_id,@v_lock_date,@v_expire_date,‘sys’,SYSDATE(),‘sys’,SYSDATE());
set p_expire_date = @v_expire_date;
end if;
if @v_type_count>0 then
set p_expire_date := null;
end if;
end;
end if;
END;

3.當某一個job執行業務前 會先調用該存儲過程 返回值是一個鎖過期時間,如果返回值爲null 則加鎖失敗 業務不執行。
加鎖:
call myTest.proc_dm_lock(‘sys’,‘sys’,1,@val1);
select @val1;
初次調用加鎖成功
再次調用:
call myTest.proc_dm_lock(‘sys’,‘sys’,1,@val1);
select @val1;
再次調用加鎖失敗

4.加鎖成功的job執行業務成功後 解鎖
– 解鎖
update config_log_quartz q
set q.expire_date = SYSDATE()-0.0001,
q.updated_by = ‘sys’,
q.updated_date = SYSDATE()
where
q.expire_date>SYSDATE()
AND q.target_type = ‘tyzhen’
AND q.target_id = ‘sys’;

當然項目中在job具體業務類上實現加鎖解鎖是通過切面來實現的,這裏不在贅述。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章