接口的冪等性實際上就是接口可重複調用,在調用方屢次調用的狀況下,接口最終獲得的結果是一致的。有些接口能夠自然的實現冪等性,好比查詢接口,對於查詢來講,查詢一次和兩次,對於系統來講,沒有任何影響,查出的結果也是同樣。
除了查詢功能具備自然的冪等性以外,增長、更新、刪除都要保證冪等性。那麼如何來保證冪等性呢?mysql
若是使用全局惟一ID,就是根據業務的操做和內容生成一個全局ID,在執行操做前先根據這個全局惟一ID是否存在,來判斷這個操做是否已經執行。若是不存在則把全局ID,存儲到存儲系統中,好比數據庫、redis等。若是存在則表示該方法已經執行。redis
從工程的角度來講,使用全局ID作冪等能夠做爲一個業務的基礎的微服務存在,在不少的微服務中都會用到這樣的服務,在每一個微服務中都完成這樣的功能,會存在工做量重複。另外打造一個高可靠的冪等服務還須要考慮不少問題,好比一臺機器雖然把全局ID先寫入了存儲,可是在寫入以後掛了,這就須要引入全局ID的超時機制。sql
使用主鍵衝突的策略進行防重,在併發量很是高的狀況下對數據庫性能會有影響,尤爲是應用數據表和主鍵衝突表在一個庫的時候,表現更加明顯。其實針對是否會對數據庫性能產生影響這個話題,我也和一些專業的DBA同窗討論過,廣泛承認的是在MySQL數據庫中採用主鍵衝突防重,在大併發狀況下有可能會形成鎖表現象,比較好的辦法是在程序中生產主鍵進行防重。數據庫
這種方法適用於在業務中有惟一標的插入場景中,好比在以上的支付場景中,若是一個訂單隻會支付一次,因此訂單ID能夠做爲惟一標識。這時,咱們就能夠建一張去重表,而且把惟一標識做爲惟一索引,在咱們實現時,把建立支付單據和寫入去去重表,放在一個事務中,若是重複建立,數據庫會拋出惟一約束異常,操做就會回滾。併發
這種方法插入而且有惟一索引的狀況,好比咱們要關聯商品品類,其中商品的ID和品類的ID能夠構成惟一索引,而且在數據表中也增長了惟一索引。這時就可使用InsertOrUpdate操做。微服務
這種方法適合在更新的場景中,好比咱們要更新商品的名字,這時咱們就能夠在更新的接口中增長一個版本號,來作冪等性。惟一的問題就是對數據表侵入較大,要爲每一個表設計一個版本號字段,而後寫一條判斷sql每次進行判斷。性能
這種方法適合在有狀態機流轉的狀況下,好比就會訂單的建立和付款,訂單的付款確定是在以前,這時咱們能夠經過在設計狀態字段時,使用int類型,而且經過值類型的大小來作冪等,好比訂單的建立爲0,付款成功爲100。付款失敗爲99spa