批处理任务通过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)
)
;
分享到:
相关推荐
综上所述,解决Spring Quartz在负载均衡环境下的重复执行问题,需要综合运用Quartz的集群特性、数据库Job Store、公平调度以及应用层面的设计策略。通过这些方法,可以确保在多服务器环境中,定时任务的执行有序且...
JavaWeb定时器是一种在Web应用程序中实现周期性任务的关键技术,它允许开发者安排任务在特定时间间隔内自动执行。在本项目中,我们看到的是一个简单的Java定时器,设计为每三秒执行一次。这个定时器可能是基于Java的...
2. 提高效率:通过定期执行任务,如数据库维护和缓存更新,可以提高系统的整体性能和响应速度。 3. 非阻塞特性:定时任务通常在后台运行,不会阻塞主线程,保证了Web应用的正常服务。 二、Java中的定时器组件 1. ...
Quartz支持 cron 表达式,可以方便地配置任务的执行时间和频率,同时还支持任务集群,能够在分布式环境中保证任务的可靠执行。 Quartz的核心概念包括: 1. **Job**:表示一个需要执行的任务,是业务逻辑的具体实现...
- **容错(Fail-over)**:集群模式下,若一台服务器故障,其他服务器可以接管其任务。 - **负载均衡(Loadbalancing)**:集群中的服务器可以根据配置自动分发任务,实现负载均衡。 5. **监听器及插件...
在Java Web开发中,定时任务是一项非常重要的功能,它允许我们按照预定的时间间隔执行特定的任务,比如数据库备份、清理缓存、发送邮件等。在这个"javaweb 定时器工程"中,主要涉及到了两个关键组件:Quartz和...
Quartz定时器是一款强大且灵活的开源作业调度框架,它允许开发者在Java应用程序中安排复杂的任务执行。Quartz不依赖任何特定的Web或应用服务器框架,因此可以独立使用,这正是"quartz定时器不依赖任何框架"这个主题...
5. **集群(Clustering)**:Quartz还支持集群部署,可以在多台服务器上部署同一个调度器实例,通过共享同一份作业和触发器的状态,实现高可用性和故障转移。 6. **插件(Plugins)**:Quartz提供了丰富的插件系统...
- **集群支持**:在多服务器环境下,Quartz可以实现负载均衡,保证任务的均匀分布和容错性。 - **监听器**:你可以定义JobListener和TriggerListener,监控Job和Trigger的生命周期事件。 通过熟练掌握Quartz定时器...
在IT行业中,定时器功能是不可或缺的一部分,尤其在系统自动化、任务调度以及服务维护等领域有着广泛的应用。Quartz是一款强大的开源任务调度库,它为Java应用程序提供了精确且灵活的定时任务管理能力。本文将深入...
Quartz是一款开源的作业调度框架,它为Java应用程序提供了强大的定时任务管理能力。在Java世界里,Quartz是实现定时任务的首选工具,其灵活性和稳定性都得到了广大开发者的好评。下面,我们将深入探讨Quartz定时器的...
"shiro+SpringMVC+Spring+mybatis+maven+mybatis 自动刷新+Quartz scheduler 定时器"是一个常见的技术栈组合,每个组件都有其特定的功能和作用。 1. **Shiro**:Apache Shiro 是一个强大且易用的Java安全框架,提供...
8. **并发与集群**:Quartz允许在多台服务器上部署同一个Scheduler实例,实现任务的负载均衡和高可用。当一个服务器故障时,其他服务器可以接管任务。 9. **错误处理与回调**:Quartz提供异常处理机制,当Job执行抛...
Quartz定时器是一款开源的作业调度框架,广泛应用于Java企业级开发中,用于实现系统任务的自动化执行。它提供了一种高度灵活的方式来安排和管理任务,使得开发者可以在应用程序中设置定时执行的任务,如数据同步、...
"Java应用多机器部署解决大量定时任务问题" Java应用多机器部署解决大量定时任务...解决Java应用多机器部署下的大量定时任务问题需要设计和实现分布式系统,并使用数据库的锁机制来确保只有一个机器能够执行定时任务。
可以采用分布式定时任务框架,如Quartz或Spring Task,配合分布式锁(如Redis Lock)来确保定时任务在任意一台活动服务器上唯一执行。 6. **数据一致性考虑**:尽管Redis有主从复制,但在特定情况下,如网络延迟或...
8. **数据库操作**:在执行更新、修改等操作时,可能涉及到与数据库的交互。需要了解SQL语句、JDBC或ORM框架(如Hibernate、MyBatis)来与数据库进行数据交换。 9. **文件操作**:对于涉及文件修改的定时任务,需要...
例如,可以通过SAN存储将Session数据统一存储在一个中心位置,这样可以在集群中任何一台服务器上访问这些数据。 4. **定时器和日志记录**:在WebLogic集群中,还需要考虑Session的过期时间以及相关的定时任务管理...