開發數據同步服務時容易犯的錯誤
未判斷是否成功獲取數據就進行下一步操作
問題描述
在同步服務中,數據的獲取通常是第一步,例如從數據庫、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數據庫

在進行數據同步的同時,沒有考慮到數據是否有獲取同步到對應的數據庫,就進行了數據的刪除。

總結
在同步服務中,數據獲取的有效性檢查是至關重要的環節。未進行充分的檢查可能導致數據丟失、系統異常等問題。通過加強異常處理、事務管理以及日志監控,可以有效降低風險,確保同步流程的穩定性和數據一致性。

浙公網安備 33010602011771號