訂單新增了「通知Email」,讓客戶可以指定另一個地址接收出貨通知。沒有填寫時,就沿用訂單原本保存的Email。正式環境如果採不停機更新,兩台網頁主機逐台部署,背景寄信程式則另外更新,就會有一段時間,新舊版本一起使用同一份資料庫。
新功能本身不複雜,但什麼時候可以讓客戶開始填寫?如果開放後需要退版,已經填進去的地址又該怎麼處理?
上線順序,要考慮還在執行的程式
這個案例可以先新增允許空值的通知Email欄位,保留原本的Email,再更新使用它的程式。空值代表沿用原地址,既有訂單因此不需要全部補上新欄位。不過,新增欄位後,舊程式的查詢與寫入是否仍然相容,還是要確認,不能直接假設它會自動忽略新欄位。
即使確認舊程式可以照常執行,網頁更新完成,也不代表寄信程式已經更新。如果這時開放填寫,舊版寄信程式仍只讀取原地址,就可能忽略客戶的新設定。程式沒有報錯,通知卻被安靜地寄錯了地方。
若改成停機更新,可以減少新舊版本同時讀寫的問題,但仍要考慮資料庫與各個服務之間的依賴。例如新版網頁需要訂單API支援通知Email,就得等API準備好,才能開放這項操作。部署順序要搭配版本相容性一起看,不能只確認每支程式各自能正常啟動。
程式退回去了,資料仍然是新的
假設所有程式都更新完成,客戶也已填入新的通知Email。過了一段時間,新版的其他功能出現問題,團隊打算退回上一版。
舊版程式可以啟動,資料表也還在,卻不代表退版後的行為正確。客戶已經指定新的通知地址,舊版仍只讀取原地址;留下新欄位,只是保住資料,沒有讓舊程式懂得使用它。
因此,判斷能不能退版,除了看資料結構是否相容,也要看舊版本能否依照目前保存的設定處理業務。新增欄位、改變狀態值,或調整資料保存方式,都可能讓原本正常的舊程式不再適用。
那麼,把資料庫一起還原到上線前呢?如果這段時間已經有人建立訂單、修改地址,整庫還原也會讓這些正常操作的結果消失。寄出去的通知更不會跟著收回。資料還原涉及要保留哪些變更、如何補回操作,不能直接當成一般退版的附帶步驟。
回退方案需要在開放功能前想好:能退到哪個版本、它是否理解新資料,以及哪些變更發生後,就必須改採修補目前版本或另外處理資料。
部署完成,不代表功能要立刻啟用
這個案例可以把部署與啟用分開。先部署一個相容版本,讓所有相關程式都懂得「有通知Email就使用,沒有就沿用原地址」,暫時不開放填寫。
等網頁、背景寄信程式與仍在執行的舊版工作都完成切換,再透過功能開關(Feature Toggle)開放填寫新欄位。這個開關控制的是能否新增或修改通知Email,後端入口也要一起受控,不能只把畫面藏起來。
這樣就能保留一個已經讀得懂新資料的回退版本。後續版本若出問題,可以評估退回這個版本,既有通知Email仍能被正確使用;若問題就出在這個相容版本本身,仍需要另外修補,不能再一路退回不認識新欄位的版本。
不過,關閉功能不會撤銷已發生的操作。即使暫停繼續填寫,已經保存的通知地址仍然有效,寄信程式不能跟著切回只讀原地址。功能開關能停止新的變更,無法把系統自動恢復成啟用前的樣子。
程式可以退回舊版,系統卻已經留下了新的資料。能不能退,不只看程式能跑,更要看舊版本是否還能正確理解上線後發生的事。
「新版出問題了,程式立刻退回上一版!」
「那剛才寫進去的資料呢?」
「資料庫也還原到半小時前!」
「太好了,客戶已經付了錢,但找不到訂單」
![]()