集群环境定时器更新数据库,只有一台应用执行
程序员文章站
2022-04-01 23:44:23
...
批处理任务通过quartz控制执行的时候,如果有多个部署,就要避免部署的不同应用上的定时任务同时执行而导致的错误。
通过oracle的行锁,控制quartz的执行。
使用spring+quartz+ibatis
ibatis配置文件中里面的查询,如果发现存在对应的行被锁,直接抛出异常返回,知道当前任务正在执行
提供互斥控制的service层方法
定时器类
建表脚本
通过oracle的行锁,控制quartz的执行。
使用spring+quartz+ibatis
ibatis配置文件中里面的查询,如果发现存在对应的行被锁,直接抛出异常返回,知道当前任务正在执行
<select id="abatorgenerated_selectByExampleForUpdate" resultMap="abatorgenerated_SysRunParamResult" parameterClass="com.huateng.system.entity.SysRunParamExample" > select id, type, systemId, key, value, createId, createTime, oprId, oprTime, RESERVER1, RESERVER2, RESERVER3 from HT_SYSRUNPARAM <isParameterPresent > <include refid="HT_SYSRUNPARAM.abatorgenerated_Example_Where_Clause" /> <isNotNull property="orderByClause" > order by $orderByClause$ </isNotNull> </isParameterPresent> for update nowait </select>
提供互斥控制的service层方法
/** * key对应到定时任务的className全称 * 配置事务 * @param key --用className作为key * @param interval --获取quartz的执行间隔,单位为毫秒 * @param multiNum --异常情况下,多少次执行后,重新执行 * @return */ public boolean localQuartzServiceIsRunning(String key,Long interval,int multiNum){ SysRunParam cur; try { cur = sysRunParamDAO.getSysRunParamForUpdate(key); System.out.println(cur); } catch (DataAccessException e) { System.out.println("执行过程冲突,DataAccessException+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"); return Boolean.TRUE; //访问报错,说明已经有执行 } catch (ResultListEmptyException e) { //没有数据就初始化数据 System.out.println("ResultListEmptyException"); SysRunParam newParam=new SysRunParam(); newParam.setId("1"); newParam.setKey(key); newParam.setOprid("system"); newParam.setOprtime(Calendar.getInstance().getTime()); newParam.setType("quartz"); newParam.setValue("ture"); newParam.setCreatetime(Calendar.getInstance().getTime()); newParam.setSystemid("2"); sysRunParamDAO.insert(newParam); return Boolean.FALSE;//更新后执行 }catch(Exception e){ System.out.println("Exception"); return Boolean.FALSE; } String statu=cur.getValue(); Date lastUpdateTime=cur.getOprtime();//上一次执行时间 long executeInterval=System.currentTimeMillis()-lastUpdateTime.getTime(); if(Boolean.parseBoolean(statu)){ //如果长时间没有执行,也该修为执行,避免宕机导致的错误. if(executeInterval>interval*multiNum){ System.out.println("executeInterval>interval*multiNum"); cur.setValue(Boolean.TRUE+""); cur.setOprtime(Calendar.getInstance().getTime()); sysRunParamDAO.updateRecord(cur); return Boolean.FALSE; }else{ return Boolean.TRUE; } }else{ //如果没有执行,先更新状态 cur.setValue(Boolean.TRUE+""); cur.setOprtime(Calendar.getInstance().getTime()); sysRunParamDAO.updateRecord(cur); return Boolean.FALSE; } } /** *定时任务完成以后更新运行状态 * @param key */ public void updateLocalQuartzLock(String key){ SysRunParam cur; try { cur = sysRunParamDAO.getSysRunParamForUpdate(key); cur.setValue("false"); cur.setOprtime(Calendar.getInstance().getTime()); sysRunParamDAO.updateRecord(cur); } catch (DataAccessException e) { e.printStackTrace(); } catch (ResultListEmptyException e) { e.printStackTrace(); } }
定时器类
public class ActivityEffectJob { /** * */ private static final long serialVersionUID = 1L; private SysRunParamService sysRunParamService; /**上一次执行的时间*/ private static long lastExecuteTime=System.currentTimeMillis(); private static final int multiNum=10; public void start() { long lastExecuteTimetemp=lastExecuteTime; lastExecuteTime=System.currentTimeMillis(); if(sysRunParamService.localQuartzServiceIsRunning(MY_CLASS_NAME,System.currentTimeMillis()-lastExecuteTimetemp, multiNum)){ System.out.println(MY_CLASS_NAME+"'s job is running"); return; } try { //works Thread.sleep(1000); } catch (Exception e) { }finally{ sysRunParamService.updateLocalQuartzLock(MY_CLASS_NAME); lastExecuteTime=System.currentTimeMillis(); System.out.println("finally:"+MY_CLASS_NAME+"'s job is finnished"); } } /** * 当前类名 */ private static final String MY_CLASS_NAME; static{ MY_CLASS_NAME = new Object() { public String getClassName() { String clazzName = this.getClass().getName(); return clazzName.substring(0, clazzName.lastIndexOf('$')); } }.getClassName(); } public SysRunParamService getSysRunParamService() { return sysRunParamService; } public void setSysRunParamService(SysRunParamService sysRunParamService) { this.sysRunParamService = sysRunParamService; } }
建表脚本
create table HT_SYSRUNPARAM ( ID VARCHAR2(30), TYPE VARCHAR2(30), PARENTTYPE VARCHAR2(30), SYSTEMID VARCHAR2(30), KEY VARCHAR2(200), VALUE VARCHAR2(200), DSC VARCHAR2(500), CREATEID VARCHAR2(30), CREATETIME TIMESTAMP(6), OPRID VARCHAR2(30), OPRTIME TIMESTAMP(6), RESERVER1 VARCHAR2(100), RESERVER2 VARCHAR2(100), RESERVER3 VARCHAR2(100) ) ;
上一篇: spring3+struts2+ibatis Demo
下一篇: 反射小计