手把手教你五分鐘搞定冪等本質(zhì)
冪等概念
冪等性原本是數(shù)學(xué)上的概念,即使公式:f(f(x)) =f(x)能夠成立的數(shù)學(xué)性質(zhì)。用在編程領(lǐng)域,則意為對同一個(gè)系統(tǒng),使用同樣的條件,一次請求和重復(fù)的多次請求對系統(tǒng)資源的影響是一致的。冪等性是系統(tǒng)服務(wù)對外一種承諾,承諾只要調(diào)用接口成功,外部多次調(diào)用對系統(tǒng)的影響是一致的。聲明為冪等的服務(wù)會(huì)認(rèn)為外部調(diào)用失敗是常態(tài),并且失敗之后必然會(huì)有重試。比如我們發(fā)起一筆付款請求,應(yīng)該只扣用戶賬戶一次錢,當(dāng)遇到網(wǎng)絡(luò)重發(fā)或系統(tǒng)問題重發(fā),也應(yīng)該只扣一次錢,具體冪等處理流程如下圖所示:

SQL中的冪等
SELECT col1 FROM tab1 WHER col2=1,無論執(zhí)行多少次都不會(huì)改變狀態(tài),是天然的冪等。
UPDATE tab1 SET col1=1 WHERE col2=1,無論執(zhí)行成功多少次狀態(tài)都是一致的,因此也是冪等操作。
UPDATE tab1 SET col1=col1+1 WHERE col2=1,每次執(zhí)行的結(jié)果都會(huì)發(fā)生變化,這種不是冪等的。
insert into user(userid,name) values(123456,'kevin') 如userid為唯一主鍵,即重復(fù)操作上面的業(yè)務(wù),只會(huì)插入一條用戶數(shù)據(jù),具備冪等性。
如userid不是主鍵,可以重復(fù),那上面業(yè)務(wù)多次操作,數(shù)據(jù)都會(huì)新增多條,不具備冪等性。
delete from user where userid=123456,多次操作,結(jié)果一樣,具備冪等性
HTTP方法中的冪等
HTTP方法的冪等性是指一次和多次請求某一個(gè)資源應(yīng)該具有同樣的副作用。
- GET方法用于獲取資源,不應(yīng)有副作用,所以是冪等的。
- DELETE方法用于刪除資源,有副作用,但它應(yīng)該滿足冪等性。例如:刪掉id為123456的帖子,調(diào)用者可以多次調(diào)用或刷新頁面而不必?fù)?dān)心引起錯(cuò)誤。
- POST方法不具備冪等性,兩次相同的POST請求會(huì)在服務(wù)器端創(chuàng)建兩份資源,它們具有不同的URI
- PUT方法具備冪等性,他所對應(yīng)的URI是要?jiǎng)?chuàng)建或更新資源的本身,對同一URI進(jìn)行多次PUT的副作用和一次PUT是相同的。
- PATCH不具備冪等性 他會(huì)將一組描述在請求實(shí)體里的更改應(yīng)用到URI標(biāo)志的資源。這組更改以 "補(bǔ)丁文檔" 的格式表示,如果URI未指向現(xiàn)有資源,服務(wù)器可能根據(jù)補(bǔ)丁文檔的類型和權(quán)限等來創(chuàng)建一個(gè)新資源。
測試角度看冪等
核心測試點(diǎn)包括:
- 用戶重復(fù)提交
- 網(wǎng)絡(luò)重發(fā)
- 消息重發(fā)
- 系統(tǒng)間重試
重點(diǎn)關(guān)注的內(nèi)容如下:
1)需要關(guān)注業(yè)務(wù)性質(zhì)和產(chǎn)品設(shè)計(jì),是否需要做到冪等,是時(shí)間維度的冪等(即冪等對象的范圍,是個(gè)人還是機(jī)構(gòu),是某一次交易還是某種類型的交易)還是空間維度的冪等(即冪等的保證時(shí)間,是幾秒、幾分鐘還是永久性的)。
2)接口的冪等測試,在做接口測試時(shí)對每個(gè)接口都思考一下是否需要冪等。
3)業(yè)務(wù)場景,特別是涉及到錢的業(yè)務(wù)場景,對失敗重試機(jī)制一定要驗(yàn)證。