概念
冪等的概念來自于抽象代數(shù),比如對于一元函數(shù)來說,滿足如下條件:
f(f(x)) = f(x)即可稱為滿足冪等性。在計算機科學(xué)中,一個操作多次執(zhí)行和一次執(zhí)行的影響相同,這樣的操作即符合冪等性。在分布式的系統(tǒng)中,服務(wù)消費方調(diào)用服務(wù)提供方的接口,多次調(diào)用的結(jié)果應(yīng)該與一次調(diào)用的結(jié)果相同,這就是分布式環(huán)境下的冪等性的語義。為什么都在強調(diào)冪等性?因為分布式服務(wù)系統(tǒng)有可能因為網(wǎng)絡(luò)不穩(wěn)定原因?qū)е乱粋€服務(wù)的接口被重復(fù)調(diào)用,避免產(chǎn)生未知的異常。
考慮如下場景是否要保證冪等性:
a.運營發(fā)起打款操作,由于網(wǎng)絡(luò)原因或者重試機制,重復(fù)打款了;
b.提交表單,由于瀏覽器卡頓,用戶多次點擊提交按鈕導(dǎo)致重復(fù)提交;
經(jīng)過分析可知上面兩種場景必須保證冪等性,不然會造成系統(tǒng)的數(shù)據(jù)異常。我們再從數(shù)據(jù)庫的操作層面分析上面的兩種場景,都是寫操作,于是我們可以分析得出數(shù)據(jù)庫的CRUD有如下特點:
新增:不具備冪等性
查詢:天然具備冪等性,因為查詢不會影響數(shù)據(jù)庫里的任何結(jié)果
修改:不具備冪等性
刪除:具備冪等性
那如何解決冪等性呢?
1,全局唯一ID
根據(jù)業(yè)務(wù)生成全局唯一的ID,調(diào)接口的時候傳入該ID,服務(wù)方會從存儲系統(tǒng)查詢是否存在這個ID,如果不存在則可調(diào)用接口,否則拒絕本次請求。
2,利用數(shù)據(jù)庫的去重
如在mysql中設(shè)置關(guān)鍵屬性為UNIQUE,當業(yè)務(wù)中重復(fù)插入的時候,拋出唯一約束異常,操作就會回滾。
3,狀態(tài)機控制
適合在有狀態(tài)機流轉(zhuǎn)的情況下,比如訂單的創(chuàng)建和付款,訂單的創(chuàng)建肯定在支付之前,這樣可以添加一個int類型的字段表示訂單的各個狀態(tài),創(chuàng)建為0,付款成功為100,失敗為99,則更新訂單的語句可以如下表示:
update order set status=#{status} where id=#{id} and status<#{status}
4,插入或者更新
在mysql中有個功能是存在則更新,不存在則插入,即在insert into語句后跟上on duplicate key update,mysql會判斷插入語句的主鍵值和數(shù)據(jù)庫現(xiàn)有的記錄是否重復(fù),如果重復(fù),則會修改原有的記錄,不重復(fù)則添加一條數(shù)據(jù)。