使用Java語言開發一個介面程式,用來獲取增量資料,請問這個介面應該如何設計,輸入引數和輸出引數分別是什么?
如何區分存量資料和增量資料,是通過主鍵ID,還是通過時間?
這個介面是對外的,外部客戶呼叫該介面,不定期的把增量資料同步到我們的資料庫中,要保證新插入的資料記錄既不能多也不能少,既不能重復,也不能遺漏。
最好能給出示例代碼,謝謝大家!
uj5u.com熱心網友回復:
這個得根據實際情況,如果資料只有插入操作,類似于日志那種的,用id就可以了。如果資料還存在修改、洗掉等操作,那建議加一個版本欄位,每次獲取的時候帶上版本號,版本號每次都自動往上遞增,當有修改或者洗掉(邏輯洗掉)的時候記錄版本號。這樣可以根據版本號進行查詢。uj5u.com熱心網友回復:
/**
* 合并資料,insert和update,主鍵可以多個
*
* @param dbset 資料庫配置
* @param table 表名
* @param list 資料源
* @param targetMain 表的主鍵
* @param targetColumn 表的所有列(包含主鍵)
* @param sourceMain 資料源的主鍵
* @param sourceColumn 資料源中所有列(包含主鍵)
* @throws Exception 捕獲例外
*/
public static void merge(DatabaseSet dbset, String table, List<Map<String, Object>> list, List<String> targetMain, List<String> targetColumn,
List<String> sourceMain, List<String> sourceColumn) throws Exception {
if (Database.saphana.equals(dbset.database())) {
String sql = SqlUtil.insert(dbset, table, targetColumn).replaceAll("insert into", "upsert") + SqlUtil.joinMain(dbset, targetMain);
sourceColumn.addAll(sourceMain);
BatchUtil.manage(dbset.connect(), sql, list, sourceColumn);
return;
}
List<String> sourceUpdateColumn = new ArrayList<String>();
for (String s : sourceColumn) {
if (!sourceMain.contains(s)) {
sourceUpdateColumn.add(s);
}
}
sourceUpdateColumn.addAll(sourceMain);
String insert = SqlUtil.insert(dbset, table, targetColumn), update = SqlUtil.update(dbset, table, targetColumn, targetMain);
List<Map<String, Object>> inserts = new ArrayList<Map<String, Object>>(),
updates = split(dbset, list, inserts, table, targetMain, sourceMain);
Object[] values = { inserts.size(), updates.size() };
log.info(EntityUtil.toJson(EntityUtil.create(Map.class, new String[] { "insert", "update" }, values, false)));
if (updates.size() > 0) {
manage(dbset.connect(), update, updates, sourceUpdateColumn);
}
if (inserts.size() > 0) {
manage(dbset.connect(), insert, inserts, sourceColumn);
}
}
uj5u.com熱心網友回復:
這個就要看你是想用什么方式來同步資料(主要是跟外部客戶協調好)我這邊剛完成的一個on-premise到cloud的移植專案是以檔案的方式(因為考慮到資料量可能很大)來同步增量資料的。也就是客戶不定期的抽取增量資料(以時間戳為準,當然,如果你的主鍵ID是自動遞增,用主鍵ID也可以)做成檔案,上傳到我這邊的服務器,服務器監視到新檔案就觸發batch執行,把檔案資料插入資料庫。
新插入的資料記錄既不能多也不能少,既不能重復,也不能遺漏,要保證這點,主要還是看你的實作方式了。我這邊的做法是客戶抽取資料的時間戳比上次抽取結束的時間戳稍往前一點(即抽出的資料做成的檔案會有少量重復資料),batch的這邊插入的時候過濾掉重復的資料。
uj5u.com熱心網友回復:
如果樓主沒表達錯誤,并且我也沒理解錯的話,情況應該是:1、你開發一個介面,給客戶呼叫
2、資料本來是在客戶那里,他定期通過呼叫介面,把增量資料傳到你的平臺上來
3、你保存增量資料
這種需求,建議:
1、開放一個 http 介面,讓對方用 http 協議,以 json 的方式把資料發給你,當然也要考慮身份認證之類的問題
2、資料要有主鍵,如果客戶不肯給主鍵,那也至少要有一個或者幾個欄位能夠唯一確定一條記錄,也就是候選鍵,這樣才能確定發過來的資料,你是要進行更新還是進行插入
3、你收到資料時,最好給客戶平臺的充足的回應資訊,比如對方發了100條過來,每條記錄處理結果,如插入、更新、失敗,這樣便于對方重發。如果這樣處理不方便,那么至少這100條資料的整體處理結果要回應給對方。
4、要考慮意外情況,比如客戶發資料給你時,正好你的服務器當機,或者路由器死機、機房停電之類的非可抗因素造成的資料接收不了。這時你應該要求對方要有失敗重發機制。
uj5u.com熱心網友回復:
還有簡單點的辦法是,你們訂個資料格式,然后你開個 ftp 服務器,對方把資料傳到你的FTP服務器上來,然后你定期掃描有沒有新檔案uj5u.com熱心網友回復:
一般會建幾張表來存放相關資料。1. 介面請求表,每次呼叫介面都要進行記錄,客戶端的id,呼叫時間,傳輸的資料量(資料記錄的條數),傳輸批次號(可以取自增主鍵的值,也可以自定義),傳輸的資料型別(用于不同型別的資料,服務端進行不同方式的處理,也就是多型)等等。
2. 介面資料表,存放每次介面傳輸的資料以及資料的處理狀態,是做批量插入操作的,將1表中的批次號也帶上,方便資料追蹤,當每條資料處理完成后,更新資料狀態。隨著時間的推移,表長度會增加,后期考慮資料遷移,或者資料銷毀。
介面設計思路。
1. 要確定一次請求是傳輸一條記錄,還是一次請求傳輸多條記錄(多條記錄時要設定最大傳輸條數)。
2. 請求的資料中需要一個唯一標識一條記錄的欄位(也可以是多個欄位組合形成的,業務邏輯上能夠標明一條資料的ID值),用于區分是否是重復傳輸的資料。
3. 請求資料是否有認證的需求,防止外來其他目的的資料進行非法提交。一般是通過融入tocken來進行認證。
4. 請求資料是否有驗證的需求,以防資料在傳輸程序中被別人攔截,更改后再傳入服務器。一般是通過對資料和客戶端ID之類的資料進行MD5(數字簽名)后放入請求記錄中,服務端采用相同演算法進行驗證。
5. 請求的資料是否有加密的需求,防止資料傳輸程序中,被第三方機構或者程式查看,造成資料泄露。
6. 上述介面的設計思路是采用推送的方式,由客戶端不定時的推送的,所以,會要求客戶端對推送的資料,采用失敗重傳的機制,方式資料丟失,服務端接收資料,要區分出哪些是重傳的資料才行。
7. 推送方式的接收資料,會有一個服務端過載的問題,如果同時接收的資料過大,服務端有時候會處理不過來,造成客戶端推送任務的超時等例外,所以,如果可能,服務端最好是有一個判斷服務端負載狀況的方案,當服務端過載時,不做資料處理,直接告訴客戶端,稍后再試。
8. 應答資料內容,一般情況下會包含錯誤代碼和文字解釋。在介面協議的檔案里面,會有一個附錄,里面有錯誤代碼表,說明,什么樣的錯誤代碼,表示什么場景下的錯誤。客戶端可以根據錯誤代碼,完善業務流程。
以上是樓主說的推送的方式進行資料傳遞。
其實,還可以拉取的方式,就是,服務器定時輪詢各個資料源,如果它們有增量資料就順便傳輸過來,如果沒有,就應答一個沒有的代碼給你。
uj5u.com熱心網友回復:
這個肯定要通過ID來區分,時間的話不靠譜,可能某段時間傳來的是幾天前漏傳的資料uj5u.com熱心網友回復:
我感覺樓主最大的問題是如何定義增量,不是什么如何定義介面,什么資料庫,什么json,什么http等。所以如何定義增量才是前提。這些要根據實際業務情況才能定義什么是增量資料。uj5u.com熱心網友回復:
既然是別人呼叫介面推送資料過來做增量,就定義一個String型別的引數,接收一個JSONArray格式的字串,再把這個JSONArray格式的字串轉成List<Map<String, Object>>,這不就是增量資料么,再呼叫我那個方法把資料合并到資料庫,就搞定了全量也是一樣,無非就是資料多一點,如果資料量特別大,就讓對方多調幾次介面
如果源資料洗掉也要同步,就再定義一個String型別的引數,接收一個JSONArray格式的字串,再根據這個引數值做delete就行
出于安全考慮,介面最好做驗簽
uj5u.com熱心網友回復:
新增修改有保存最新時間的話,可以傳時間戳,但這個得客戶端自己維護時間戳,這樣才是最穩妥的,畢竟是否同步成功也就客戶端清楚,而不是服務端,也保證了靈活度和容錯空間uj5u.com熱心網友回復:
我覺得挺簡單的 啊,資料必須要有一個唯一欄位,在表中設定這個欄位為唯一索引,如果重復了就會報錯!轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/9701.html
標籤:Java EE
下一篇:智能控制系統的二級模塊是什么
