`
xly1981
  • 浏览: 142742 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

集群环境定时器更新数据库,只有一台应用执行

 
阅读更多
批处理任务通过quartz控制执行的时候,如果有多个部署,就要避免部署的不同应用上的定时任务同时执行而导致的错误。

通过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)
)
;
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics