开发数据同步服务时容易犯的错误

未判断是否成功获取数据就进行下一步操作

问题描述

在同步服务中,数据的获取通常是第一步,例如从数据库、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";
}

致命问题

具体流程如下:

  1. 获取数据总页数。
  2. 分页获取更新数据。
  3. 删除旧数据。

然而,之前的实现存在问题:

  • 未对“分页获取更新数据”是否成功进行判断,就直接执行“删除旧数据”的操作。
  • 在现成环境中,如果设置分页大小为 10000,对方接口会报错,导致更新视频数据失败。
  • 由于未检查更新数据是否成功,程序继续执行删除旧数据的操作,最终导致数据库表中的数据被清空。

典型案例2:MySql中的数据同步到PG数据库

image

在进行数据同步的同时,没有考虑到数据是否有获取同步到对应的数据库,就进行了数据的删除。
image

总结

在同步服务中,数据获取的有效性检查是至关重要的环节。未进行充分的检查可能导致数据丢失、系统异常等问题。通过加强异常处理、事务管理以及日志监控,可以有效降低风险,确保同步流程的稳定性和数据一致性。

posted @   xiecb  阅读(25)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
点击右上角即可分享
微信分享提示