iT邦幫忙

2026 iThome 鐵人賽

DAY 15
0
AI 自動化

沒有工程師的旅行社,長出節省三個人力,並且讓重複事情都給電腦自動執行的系統系列 第 15 篇

兩個系統都能改,資料就會打架:雙向同步的三條規則與兩個雷

  • 分享至 

  • xImage
  •  

兩邊都能改,資料就會打架

真程旅行社的客戶資料同時活在兩個地方:一套線上資料庫系統,還有幾張同事習慣用的試算表。一開始是各用各的,後來想把兩邊接起來,讓改一邊、另一邊自動跟著更新。做下去才發現,雙向同步這件事,比單向搬資料難上不只一個等級。

問題出在「兩邊都能改」

單向同步很單純:資料庫改了,寫回試算表就好,永遠只有一個方向,衝突不可能發生。雙向就不一樣了——同事在試算表上改了一格,同一時間系統那邊也被別的流程改了同一列,兩邊都覺得自己手上的是最新版本,同步的時候該聽誰的,就成了問題。

先解決「怎麼知道誰比較新」

第一步是兩邊都要有一個「最後修改時間」欄位,同步的時候比這個時間戳,新的蓋過舊的。不能單純比對內容有沒有不一樣——內容不一樣只告訴你「有人改過」,沒告訴你「誰先誰後」。

這一步有兩個坑,都是實際撞到才知道的。

第一個是時區。兩套系統回傳的時間格式不一樣,一邊帶時區資訊、一邊是沒有時區的當地時間。直接拿字串比大小,結果是差了八小時——舊的那一版一直被判定成比較新,反覆蓋掉新資料。修法是所有時間戳進到比對邏輯之前,一律先正規化成同一個基準(我統一轉成帶時區的格式再比),不讓任何一邊的原始格式進到判斷式裡。

第二個是精度。一邊記到秒、一邊記到毫秒,秒數相同的兩筆會被判定成「一樣新」,然後落到未定義的行為裡。後來統一截到秒,並且明確規定「相同就當成衝突」,不要讓它靜靜地走到某個分支。

同時被改怎麼辦:標記,不要自動選邊

如果兩邊的時間戳落在幾秒之內,我不讓程式自己挑一邊蓋過去,而是把這一列標成衝突、發通知請人決定要留哪一版。

會給幾秒的容差,是因為同步本身就有延遲——A 邊剛寫完、同步程式還沒跑到,B 邊就被人改了,這種情況從時間戳上看幾乎是同時發生。硬要分出先後,等於用一個隨機的結果決定客人的資料。

自動選錯一次的代價,遠高於多花十秒讓人看一眼。這條原則跟前面講自動回信、講飯店報價辨識時是同一套:程式能明確判斷的才自動處理,判斷不了的老實標出來。

同步要能重複跑而不出事

同步程式隨時可能重跑——排程重疊、上一輪跑到一半失敗、同事手動點了一次。所以它必須設計成跑幾次結果都一樣。

做法是在真正寫入之前,先比一次「我準備要寫的內容」跟「對方現在的內容」。一模一樣就跳過,連寫入動作都不發生。這樣除了避免重複寫入,還有一個附帶好處:對方的最後修改時間不會被一次沒有實質變更的寫入給刷新——否則每跑一輪就把時間戳往前推一次,下一輪比對的時候就分不出誰才是真的被改過。

兩個踩過的雷

刪除完全沒同步。 一開始只處理新增跟修改,沒想到刪除。同事在試算表刪掉一列,系統那邊完全不知道,留下一筆試算表上已經不存在、但系統裡還活著的殭屍資料。後來改成軟刪除:試算表那邊要刪的列先標記,同步程式看到標記才去把對應資料下架,不靠「比對列數有沒有減少」去猜——因為列數減少也可能是同事插錯行、或是篩選狀態改變。

欄位順序被調亂,整組資料錯位。 同步邏輯一開始是照欄位順序對應第幾欄對第幾欄。某天同事為了看得順眼,把試算表的兩個欄位對調,結果電話寫進了信箱欄、信箱寫進了備註欄,而且程式完全沒報錯。後來全部改成用欄位名稱對應,另外維護一份對應表放在設定檔裡,不寫死在程式碼;新增欄位只要改設定檔,不用動程式。

如果你也是旅行社

如果你的資料同時活在兩個系統裡,先問自己一句:真的兩邊都要能改嗎?如果可以,盡量固定一邊是唯一的正本,另一邊只做顯示用途,雙向同步能不做就不做——它省下來的方便,往往比不上事後追查資料打架花掉的時間。真的非做不可,就先把時間戳正規化、衝突標記、軟刪除這三件事做好,再談功能。


上一篇
每封詢問信都要從零開始寫:讓 AI 給草稿,但絕不讓它按寄出
下一篇
掛號招領單被忘記、過期退回:一張會自己提醒的清單
系列文
沒有工程師的旅行社,長出節省三個人力,並且讓重複事情都給電腦自動執行的系統 共 18 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言