最終同步策略
因為一些原因,對之前的同步策略進行了修改,原有策略:同步策略選擇。現在的同步策略如下:
名詞解釋
anchor:同步錨點,用時間戳來表示,用來表示某項記錄最後同步時間
modified:修改時間,用時間戳來表示,用來表示某項紀錄內容實際最後修改時間
客戶端設計
每條表項包含兩個用來同步用的字段:
status:用來標識記錄的狀態
modified:記錄每條記錄最後修改時間
status | 含義 |
---|---|
0 | 本地新增 |
-1 | 標記刪除 |
1 | 本地更新 |
9 | 已同步 |
另外,保存一個anchor,記錄服務端同步過來的時間戳;若尚未進行任何同步,anchor為-1
服務端設計
每條表項包含兩個用來同步用的字段:
modified:記錄每條記錄最後修改時間
anchor:記錄每條記錄與客戶端時間最後同步時間
雙向同步過程
初始狀態下,我們假設客戶端和服務端的表各有兩條數據
客戶端:
id | name | phone | status | modified |
---|---|---|---|---|
1 | Ken | 18612345678 | 9 | 2 |
2 | Jim | 13888888888 | 9 | 3 |
anchor = 4
服務端:
id | name | phone | modified | anchor |
---|---|---|---|---|
1 | Ken | 18612345678 | 2 | 4 |
2 | Jim | 13888888888 | 3 | 4 |
此時,客戶端與服務端的數據是完全同步好了的
Client在時間5增加1條記錄
id | name | phone | status | modified |
---|---|---|---|---|
1 | Ken | 18612345678 | 9 | 2 |
2 | Jim | 13888888888 | 9 | 3 |
3 | Tim | 12345678 | 0 | 5 |
Client在時間6修改2條記錄
id | name | phone | status | modified |
---|---|---|---|---|
1 | Ken | 2333333 | 1 | 6 |
2 | Jim | 010-12345678 | 1 | 6 |
3 | Tim | 12345678 | 0 | 5 |
由於還未同步,anchor仍為4
Server由於在時間8與另一客戶端同步,從而修改2條記錄
id | name | phone | modified | anchor |
---|---|---|---|---|
1 | Ken | 6666666666 | 7 | 8 |
2 | Jim | 77777777777 | 4 | 8 |
Client發送本地更新
客戶端發送本地更新,即status為0、1或-1的表項,執行sql語句:
SELECT * FROM table WHERE status < 9
找出客戶端需要同步到服務端的記錄。下表中的數據是發送的同步消息
id | name | phone | status | modified |
---|---|---|---|---|
1 | Ken | 2333333 | 1 | 6 |
2 | Jim | 010-12345678 | 1 | 6 |
3 | Tim | 12345678 | 0 | 5 |
anchor = 4
Server在時間9處理同步消息
首先處理第一條數據
id | name | phone | status | modified |
---|---|---|---|---|
1 | Ken | 2333333 | 1 | 6 |
服務端收到請求後,對比客戶端的modified和服務端的modified,保留modified較晚一項;在這裏,保留服務器的數據,不進行修改。
然後處理第二條數據
id | name | phone | status |
---|---|---|---|
2 | Jim | 010-12345678 | 1 |
服務端收到請求後,對比客戶端的modified和服務端的modified,保留modified較晚一項;在這裏,保留客戶端修改後的數據,並將anchor修改為此次同步時間。
最後處理第三條數據
id | name | phone | status | modified |
---|---|---|---|---|
3 | Tim | 12345678 | 0 | 5 |
如果得知status = 0,直接插入即可,並將anchor修改為此次同步時間。
服務端經過這兩次操作後,數據表如下
id | name | phone | modified | anchor |
---|---|---|---|---|
1 | Ken | 6666666666 | 7 | 8 |
2 | Jim | 010-12345678 | 6 | 10 |
3 | Tim | 12345678 | 5 | 10 |
Client根據響應更新本地記錄
服務端處理完數據後,還要響應客戶端的請求,將所有anchor大於客戶端anchor = 4的表項發送給客戶端,如下
id | name | phone | modified | anchor |
---|---|---|---|---|
1 | Ken | 6666666666 | 7 | 8 |
2 | Jim | 010-12345678 | 6 | 10 |
3 | Tim | 12345678 | 5 | 10 |
並發送同步時間anchor = 9
收到響應後,客戶端就開始執行UPDATE了,對每一項進行修改、將status改為9,並將anchor改為最後修改時間7。
客戶端現在的數據表如下:
id | name | phone | status | modified |
---|---|---|---|---|
1 | Ken | 6666666666 | 9 | 7 |
2 | Jim | 010-12345678 | 9 | 6 |
3 | Tim | 12345678 | 9 | 5 |
並將anchor修改為anchor = 9。
客戶端刪除記錄
邏輯刪除記錄:
|id |name |phone |status |modified |
|-|-|-|-|-|
|1 |Ken |6666666666 |-1 |7 |
|2 |Jim | 010-12345678 |9 |6 |
|3 |Tim |12345678 |9 |5 |
客戶端發送消息到服務端
根據status < 9,將邏輯刪除的記錄發送至服務端,服務端收到消息後,將該記錄移至deleted_table(相當於時光機,以後可以進行數據的恢復)表中
id | name | phone | modified | anchor |
---|---|---|---|---|
1 | Ken | 6666666666 | 7 | 12 |
服務端響應客戶端的請求????
客戶端收到響應
客戶端直接進行物理刪除
服務端刪除記錄
如果客戶端從服務端獲取的增量信息中包含刪除記錄的消息,則客戶端直接進行物理刪除
最終同步策略