最近做了一个用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" class="org.springframework.scheduling.quartz.JobDetailBean"> <property name="jobClass"> <value>com.ngworld.insurancecard.db.ListenerQuartz</value> </property> <property name="jobDataAsMap"> <map> <entry key="timeout"><value>5</value></entry> <entry key="dmpService"><ref bean="dmpService"/></entry> </map> </property> </bean> <bean name="simpleQuartzTriggerlistenQuartz" class="org.springframework.scheduling.quartz.CronTriggerBean"> <property name="jobDetail"> <ref bean="listenQuartz"/> </property> <property name="cronExpression"> <value>0 0 0 * * ?</value> </property> </bean>
定时器代码:
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); } } }