天天看點

程式設計思想之幂等性 | 程式設計之道

前言

今年年初遇到項目災難,解決了不少問題,這是其中一個問題。很早的時候寫的,學以緻用的。今天看到還有這樣一篇稿文,那就整理下分享給大家學習!

程式設計思想之幂等性

什麼是幂等性

既然幂等性源于數學,那我就使用數學公式來表示,即可一目了然!

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、即使用戶端請求後與服務端失去了聯系,并且服務端處理成功,用戶端處于假死的狀态并再次請求取款,也是傳回第一次的結果,并且是迅速的響應。

價值源于技術,技術源于分享!