spring+quartz执行动态定时任务
??最近做了一个用java实现oracle备份的业务实现,现理清一下思路,做个备份^_^
业务难点:
1.由于要执行的定时任务是可以修改的,也就是动态的,用户可以选择是否要执行自动备份,什么时候备份,间隔多长时间备份一次
首先考虑到用quartz,但是quartz是需要配置的,而且用户如果不想要自动备份需要停止的时候,如果只单单使用quartz是很难办到的,在得到了众多网友的帮助下,终于想通了
思路如下:
使用quartz定义每隔一小时,查询一遍数据库autodb表,autodb表中仅有一条记录,
create table AUTODB
(
? ID???????? NUMBER(10) not null,
? ISAUTO???? CHAR(1) default 0,
? NEXTTIME?? DATE,
? TYPE?????? NUMBER(1) default 1,
? CYC????? NUMBER(2) default 1,
? HOUR???? NUMBER(2) default 0,
? MINUTE?? NUMBER(2) default 0,
? constraint PK_AUTODB primary key (ID)
);
insert into AUTODB(id,isauto,type,cyc) values(1,0,1,1);
/** * 是否备份,0不备份,1备份 */private String isAuto;/** * 开始的小时时间 */private int hour;/** * 开始的分钟时间 */private int minute;/** * 备份的类型,1按天,2按月,3按季度,4按年 */private int type;/** * 间隔周期 */private int cyc;private Date nextTime;
?quartz是在spring下配置的,每个1小时执行一次,内容如下:
<bean name="listenQuartz"name="code">import java.util.Calendar;import java.util.Date;import org.quartz.JobExecutionContext;import org.quartz.JobExecutionException;import org.springframework.scheduling.quartz.QuartzJobBean;import com.ngworld.insurancecard.service.DMPService;import com.ngworld.insurancecard.vo.AutoDB;public class ListenerQuartz extends QuartzJobBean {private DMPService dmpService;public ListenerQuartz(){}protected void executeInternal(JobExecutionContext context) throws JobExecutionException {AutoDB db = dmpService.getAutoDB();String temp = db.getIsAuto().equals("1")?"是":"否";System.out.println("定时检测是否需要备份 : "+temp);if(db.getIsAuto().equals("1")){Date d = new Date();Calendar next1 = Calendar.getInstance();next1.setTime(d);//next1.add(Calendar.MINUTE, 1);next1.add(Calendar.HOUR_OF_DAY, 1);next1.add(Calendar.SECOND, 1);//获取下一次执行的时间Date nexttime = db.getNextTime();//如果当前时间在下一次执行时间之后,则需要增加下一次执行时间,直到当前时间在下次执行时间之前if(d.after(db.getNextTime())){//这里使用while是说明,可能一次的增加无法使下次执行时间大于当前时间,所以要循环增加while(d.after(db.getNextTime())){db.setNextTime(getNextTime(db));if(d.before(db.getNextTime())){break;}}//把下一次执行的时间保存到数据库dmpService.updateAutoDB2(db);}Date d2 = next1.getTime();//判断当前时间增加1小时后,是否是在下次执行时间之后,如果是,则说明,不到1个小时内就需要执行任务了,//所以需要穿件timetask定时器任务,创建一个定时器线程在下次执行的时间执行任务if(d2.after(nexttime)){TimeTask t = new TimeTask(db.getNextTime(),dmpService);t.start();}}}public void setDmpService(DMPService dmpService) {this.dmpService = dmpService;}public Date getNextTime(AutoDB db){Calendar c = Calendar.getInstance();c.setTime(db.getNextTime());//1按天,2按月,3按季度,4按年,5按分钟if(db.getType()==1){c.add(Calendar.DATE, db.getCyc());}else if(db.getType() == 2){c.add(Calendar.MONTH, db.getCyc());}else if(db.getType() == 3){c.add(Calendar.MONTH, db.getCyc()*3);}else if(db.getType()==4){c.add(Calendar.YEAR, db.getCyc());}else if(db.getType()==5){c.add(Calendar.MINUTE, db.getCyc());}return c.getTime();}}?
定时器任务代码:
public class TimeTask { private Date date; private DMPService dmpService; public TimeTask(Date _date,DMPService _dmpService) { this.date = _date; this.dmpService = _dmpService; } public void start() { System.out.println("执行定时数据库备份"); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd-HH-mm"); String backupName = sdf.format(date); DMP dmp = new DMP(); dmp.setName(backupName); SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); dmp.setTime(sdf2.format(date)); dmp.setType("1"); boolean bool = dmpService.saveDmp(dmp); if(bool){ bool = dmpService.exeBackUp(dmp); } }}?