實(shí)戰(zhàn)第24期:綜合項(xiàng)目實(shí)戰(zhàn)(四)用版本號(hào)處理并發(fā)更新,避免舊請(qǐng)求覆蓋新?tīng)顟B(tài))
文章目錄引言:沒(méi)有數(shù)據(jù)競(jìng)爭(zhēng),為什么還會(huì)改錯(cuò)?一、本篇學(xué)習(xí)目標(biāo)與準(zhǔn)備二、鎖和版本號(hào),分別解決什么問(wèn)題?1. Mutex 保護(hù)正在發(fā)生的內(nèi)存操作2. 版本號(hào)判斷讀取之后有沒(méi)有發(fā)生修改3. 兩個(gè)頁(yè)面的請(qǐng)求會(huì)怎樣變化?三、先把版本規(guī)則約定清楚1. 什么時(shí)候增加版本?2. 舊版本碰巧與當(dāng)前狀態(tài)相同,能否直接成功?3. 它和冪等性是什么關(guān)系?四、讓版本條件貫穿 Handler、Service 和 Store1. 修改存儲(chǔ)接口2. Handler 為什么繼續(xù)使用指針?3. 用可識(shí)別錯(cuò)誤區(qū)分沖突五、內(nèi)存版本:比較與修改必須放在同一個(gè)鎖里六、SQLite 版本:把比較條件寫進(jìn) UPDATE1. 為什么“先 SELECT,再 UPDATE”不夠?2. 沒(méi)返回行,不一定代表任務(wù)不存在3. 為什么限制一個(gè)連接仍然需要版本號(hào)?七、已有數(shù)據(jù)庫(kù)怎么增加 version?1. 只改 CREATE TABLE 不會(huì)修改舊表2. 重啟時(shí)不能把版本重新設(shè)為13. 本篇遷移的適用范圍八、實(shí)際走一遍:成功、沖突、刷新、再修改1. 啟動(dòng)服務(wù)2. 創(chuàng)建任務(wù)3. 頁(yè)面A設(shè)置完成4. 模擬頁(yè)面B提交舊版本5. 讀取最新任務(wù)后,明確要求恢復(fù)未完成九、前端收到409,怎樣處理才有意義?1. 保留讀取時(shí)拿到的版本2. 為什么不能自動(dòng)刷新版本后再次寫入?3. 還需要防重復(fù)點(diǎn)擊嗎?十、測(cè)試要檢查返回值,也要檢查沒(méi)有發(fā)生什么1. 內(nèi)存與 SQLite 共用版本行為測(cè)試2. 讓多個(gè)請(qǐng)求真正競(jìng)爭(zhēng)同一版本3. HTTP 與遷移測(cè)試4. 本次實(shí)際驗(yàn)證范圍十一、實(shí)戰(zhàn)練習(xí)與下一步練習(xí)1:增加標(biāo)題編輯練習(xí)2:測(cè)試狀態(tài)變回原值練習(xí)3:設(shè)計(jì)沖突提示參考資料?創(chuàng)作者:全棧弄潮兒?? 個(gè)人主頁(yè):全棧弄潮兒的個(gè)人主頁(yè)??? 個(gè)人社區(qū),歡迎你的加入:全棧開(kāi)發(fā)社區(qū)?? 專欄:Go零基礎(chǔ)實(shí)戰(zhàn)引言:沒(méi)有數(shù)據(jù)競(jìng)爭(zhēng),為什么還會(huì)改錯(cuò)?第21篇,我們給內(nèi)存 map 加了鎖;第22篇把任務(wù)保存到 SQLite;第23篇又增加了分頁(yè)和狀態(tài)篩選??雌饋?lái),任務(wù)已經(jīng)能安全地創(chuàng)建、查詢和修改。但假設(shè)你打開(kāi)兩個(gè)頁(yè)面,它們都顯示同一條任務(wù)未完成:頁(yè)面A把任務(wù)設(shè)為已完成,保存成功。頁(yè)面B還停留在舊畫(huà)面,稍后保存表單,把里面的completed=false發(fā)給服務(wù)端。服務(wù)端照單全收,任務(wù)又變回未完成。兩次請(qǐng)求即使嚴(yán)格