开发数据同步服务时容易犯的错误,然而,开发者有时会忽
分享于 点击 14355 次 点评:28
开发数据同步服务时容易犯的错误,然而,开发者有时会忽
未判断是否成功获取数据就进行下一步操作
问题描述
在同步服务中,数据的获取通常是第一步,例如从数据库、API 或其他数据源中拉取数据。然而,开发者有时会忽略对获取数据的有效性进行检查,直接进入下一步操作(如更新数据或删除旧数据)。如果数据获取失败或返回空值,可能会导致后续操作异常,甚至引发数据丢失或系统崩溃。
典型案例1:同步海康视频列表
一个定时 job 需要每天从海康远程 API 获取视频列表数据,然后更新本地数据库。如果未检查 API 返回的数据是否为空或是否符合预期格式,可能会导致以下问题:
- 如果 API 返回空数据,程序可能尝试更新一个空对象,导致数据库中数据被覆盖为空。
- 如果 API 返回异常数据(如格式错误),程序可能抛出异常,影响同步流程。
具体代码
log.info("开头同步海康数据");
ArtemisConfig artemisConfig = GetArtemisConfigInfoConfigByKey(); //读取配置 hikconfig
HikRequest hikRequest = new HikRequest();
String first = hikRequest.SendCameras(1, 10, artemisConfig);
//log.info("获取总数据的内容是"+first);
JSONObject jsonObject = JSON.parseObject(first);
String code = jsonObject.getString("code");
if (code.equals("0")) {//判断能获取数据
//log.info("获取总数据成功");
JSONObject data = jsonObject.getJSONObject("data");
Integer total = data.getInteger("total");
log.info("获取总数据是"+total);
Integer pageSize = 1000;
Integer totalPage = (total + pageSize - 1) / pageSize;
Integer pageNo = 1;
String connStr = param;
DataTemplate postgresqlDataTemplate = DatabaseUtil.getDataTemplate(DataSourceType.POSTGRESQL.toString(),
connStr
);
while (pageNo <= totalPage) {
log.info("开始" + pageNo + "页");
String result = hikRequest.SendCameras(pageNo, pageSize, artemisConfig);
//log.info("获取数据内容是"+result);
List<Map<String, Object>> maps = hikRequest.GetCameraList(result);
if (!maps.isEmpty()) {
log.info("获取" + maps.size() + "条数据");
hikRequest.SaveCameraList(maps, postgresqlDataTemplate);
pageNo++;
} else {
log.info("获取 0条数据");
break;
}
}
//删除更新时间是前天的数据;
LocalDate yesterday = LocalDate.now().minusDays(30);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
String formattedDate = yesterday.format(formatter);
String sql = "delete from hik_camera where data_update_time < '" + formattedDate + "';";
postgresqlDataTemplate.execute(sql);
//postgresqlDataTemplate.execute("ANALYZE VERBOSE hik_camera; ");
//视频 卡口 人像 统计摄像头数量
statisticCamera(postgresqlDataTemplate);
log.info("海康摄像头统计数据表 hik_camera_statistic 更新成功");
postgresqlDataTemplate.close();
}
return "OK";
}
致命问题
具体流程如下:
- 获取数据总页数。
- 分页获取更新数据。
- 删除旧数据。
然而,之前的实现存在问题:
- 未对“分页获取更新数据”是否成功进行判断,就直接执行“删除旧数据”的操作。
- 在现成环境中,如果设置分页大小为 10000,对方接口会报错,导致更新视频数据失败。
-
由于未检查更新数据是否成功,程序继续执行删除旧数据的操作,最终导致数据库表中的数据被清空。
典型案例2:MySql中的数据同步到PG数据库
在进行数据同步的同时,没有考虑到数据是否有获取同步到对应的数据库,就进行了数据的删除。
总结
在同步服务中,数据获取的有效性检查是至关重要的环节。未进行充分的检查可能导致数据丢失、系统异常等问题。通过加强异常处理、事务管理以及日志监控,可以有效降低风险,确保同步流程的稳定性和数据一致性。
用户点评