前言
今年年初遇到專案災難,解決了不少問題,這是其中一個問題。很早的時候寫的,學以致用的。今天看到還有這樣一篇稿文,那就整理下分享給大家學習!程式設計思想之冪等性
什麼是冪等性
既然冪等性源於數學,那我就使用數學公式來表示,即可一目瞭然!
f(f(x)) = f(x)
顯然,從上面的二元函式可以看出,無論x
(等冪元素)被函式y
無限地執行運算,它的結果都是相同的。在計算機程式設計領域中,我們可以這麼定義冪等性:在呼叫某個方法、介面中,我們使用相同的引數(相同的特定引數)
,其返回值都是相同的,我們便可稱方法、介面具有冪等性。從信仰上說,冪等性是一種承諾,只要一次答應某個承諾,其承諾內容都是不會改變的。
Methods can also have the property of “idempotence” in that (aside from error or expiration issues) the side-effects of N > 0 identical requests is the same as for a single request.
如何理解冪等性
理解性的理論,舉例子掌握最快。
- 無心舉例,看場景更易理解。哈哈
冪等性場景設計
下單處理
這個例子曾經出現在我的身邊:微信服務端在搞事情!
客戶端提交資料超過十秒後,他會定時在十秒後自行斷開並自動再次發起請求,請求的資料體一模一樣,但是這樣的請求是不合法的,屬重複請求。如何解決此事呢?可以使用冪等性作為一個良好的解決方案。為解決此問題,在此先謝謝騰訊大佬CC
,後會無期!
原本的方法是這樣設計的
function add($userToken, $orderMessage){
//todo
}
這樣處理那就不能規避重複請求了。
基於冪等性來解決此問題,改進的設計方法
function add($seq,$userToken, $orderMessage){
// 現根據seq來判斷是否已經處理過了,是的話就返回第一次處理的結果
$resultJson = $this->redis->get('***_pre_' . $seq);
if(false != $resultJson){
return $resultJson;
}
// 既然沒有處理過,那就正式處理
// todo
// 處理完了,沒有問題那就將結果儲存起來
// todo
return $resultJson;
}
冪等性
屬於解決此問題的一部分,是解決方案的一部分,還有另一部分是非同步
。
提現
基於冪等性設計 | 防止使用者多次點選(後端是不相信前端處理的
)或者突然網路異常等情況下,可以保持資料的一致性。
兩個步驟:
- 後端生產票據 | 生產隊時給你發糧票,你才有機會拿錢去購買柴米油鹽醬醋茶
- 根據上一步拿到合法的票據來提現
function createTicketSequence($user) : string{
// todo
}
function withdraw($ticketSequence,$user,$amount){
// todo
}
場景理解
1、使用者在取款的時候,客戶端先帶上token
請求服務端生成一個合法的取款憑證ticketSequeuence
2、使用者在輸入取款金額並確認取款後,客戶端將會帶上使用者登入憑證userToken
、取款票據ticketSequence
以及取款金額amount
進行請求
3、服務端接收到請求後,先校驗userToken
,校驗失敗則返回重新登入,否則換取user物件
4、使用者鑑權通過後,那麼再來校驗取款票據ticketSequence
,票據不合法,那麼取款失敗,否則繼續進行取款,一直到取款成功並根據票據作為冪等值來儲存提現成功的結果
5、即使客戶端請求後與服務端失去了聯絡,並且服務端處理成功,客戶端處於假死的狀態並再次請求取款,也是返回第一次的結果,並且是迅速的響應。
本作品採用《CC 協議》,轉載必須註明作者和本文連結
價值源於技術,貢獻源於分享 | 筆記分享歸檔
No matter where I am, I will reply you immediately when I see the email.
My Email: echo "YUBzYW1lZ28uY29tCg==" | base64 -d
個人比較喜歡分享,若有不對的地方非常感謝指出
相互學習、共同進步~