最近公司项目因为要在台湾使用,所以在台湾那边搭了一个服务器和RDS。而这个项目的大陆服务器是在上海这边,所以需要将上海服务器RDS上的数据同步到台湾的RDS上。
实现思路是这样的,先在台湾服务器上安装一个Mysql,然后将RDS上的数据和Mysql进行过主从同步,然后再将Mysql上的数据同步到台湾的RDS上,第一步已经弄好了,我只负责第二步。
开始想的是弄两个数据源,用Hibernate分别对两个数据库进行操作。但是配置完后连接Mysql的Hibernate一直报No Session in Current Thread 错误,网上找了一些解决办法,说使用openSession代替getSession,但是项目的Dao层都是继承与一个BaseDao,BaseDao里用的是getSession的方式获得Session,因为整个项目的Dao都是继承在这个BaseDao,所以又不能修改BaseDao,最后没办法只能采用JDBC的方式访问Mysql
。
然后开始具体实现,首先要清楚是将Mysql上的数据同步到RDS上,先在RDS上将需要同步的表建好,字段和类型都和Mysql上的一样。然后再建立一个同步记录表,我这里叫SyncRecord,这个表有几个字段:1.版本号、2.数据编号、3.表名。具体的作用到后面再来看。表都建好了以后,开始写逻辑代码,一个表一个表进行同步,以课程表(Course)为例,Course中的字段有:1.版本号,2.课程编号,3.课程名称等。
1.使用JDBC将Mysql上Course表的所有记录查询出来,保存在CourseList里。
2.使用Hibernate将RDS上的SyncRecord表中的表名为Course的数据查询出来,保存在SyncRecordList里。所以同步记录表中的表名字段就是用来记录进行同步的表的表名的。
3.判断SyncRecordList是否为空,如果为空,说明Course表中的记录都没有进行过同步,则将CourseList中的数据一次取出来插入到RDS上的Course表中,同时每条记录也要往同步记录表中插数据,记录同步数据的表名,数据的编号(即Course表中的课程编号),数据的版本号,表示这条记录已经进行了同步。如果不为空,则循环取出CourseList中的数据与同步记录表(SyncRecordList)中的数据进行对比。
4.如果两条数据的编号相同,即课程编号等于同步记录表的数据编号,则说明这条记录之前同步过,然后比较这两条数据的版本号,如果版本号相同,这表示这条记录不需要更新,如果版本号不同,则说明这条记录已经过时需要更新。
5.更新操作就是根据这条记录的课程编号,去RDS上的Course表中查出这条记录,然后将新的数据更新进去。同时更新同步记录表中这条记录的版本号,保证版本和Mysql上的一致,避免重复更新。
List<Course> sourceList = readDao.listAllCourse();
List<SyncRecord> syncRecordList = syncRecordDao.listSyncRecord("Course");
if (sourceList != null) {
for (Course sourceCourse : sourceList) {
String sourceNo = sourceCourse.getCourse_no();
Long sourceVersion = sourceCourse.getVersion();
if (sourceNo != null) {
boolean isExist = false;
if (syncRecordList != null) {
for (SyncRecord syncRecord : syncRecordList) {
String data_no = syncRecord.getData_no();
Long data_version = syncRecord.getData_version();
if (sourceNo.equals(data_no)) {
isExist = true;
if (sourceVersion != data_version) {
Course targetCourse = courseDao.findCourse(data_no);
Long tempId = targetCourse.getId();
BeanUtils.copyProperties(sourceCourse, targetCourse);
targetCourse.setId(tempId);
courseDao.updateObject(targetCourse);
// 更新SyncRecord
SyncRecord sr = syncRecordDao.getSyncRecord("Course", data_no);
sr.setData_version(sourceVersion);
syncRecordDao.updateObject(sr);
}
break;
}
}
}
if (false == isExist) {
Course targetCourse = new Course();
BeanUtils.copyProperties(sourceCourse, targetCourse);
courseDao.createObject(targetCourse);
// 添加SyncRecord
SyncRecord syncRecord = new SyncRecord();
syncRecord.setSyncRecord_no(OpenID.generateOpenId());
syncRecord.setTable_name("Course");
syncRecord.setData_no(sourceNo);
syncRecord.setData_version(targetCourse.getVersion());
syncRecordDao.createObject(syncRecord);
}
}
}
}