參考連接html
firstdreamjava
CHEN川mysql
concurrencyweb
mvvcredis
摘自百度百科。數據庫
冪等(idempotent、idempotence)是一個數學與計算機學概念,常見於抽象代數中。編程
在編程中一個冪等操做的特色是其任意屢次執行所產生的影響均與一次執行的影響相同。冪等函數,或冪等方法,是指可使用相同參數重複執行,並能得到相同結果的函數。這些函數不會影響系統狀態,也不用擔憂重複執行會對系統形成改變。例如,「setTrue()」函數就是一個冪等函數,不管屢次執行,其結果都是同樣的.更復雜的操做冪等保證是利用惟一交易號(流水號)實現。後端
不管是單機或者分佈式系統都會遇到併發的問題,除了使用相似流量控制等的方法以外,當請求真正到達後端服務器以後,冪等設計
就能夠做爲一種解決方案了。api
基於消息隊列的分佈式架構的系統中,因爲各類緣由,好比網絡波動等,隊列裏面的消息就會重發,從本質上來講,系統自動產生了一個併發請求。簡單一點也能夠理解爲一個webapi接口被徹底「相同」的參數調用了屢次,這時候冪等就派上用處了。
看了一些文章,總結一下基本的手段。
總的來講,冪等實現中關鍵的實際上是防併發的問題。系統只要先防止併發問題,而後再根據惟一的業務主鍵返回對應的結果就好。
.net的lock或者java的ReentrantLock等高級語言中都有關鍵字,基本的用法就是構造一個對象,對於關鍵的步驟,lock這個對象,而後執行業務代碼,操做完成再釋放。
咱們在執行完全部的數據庫操做以後,往一張冗餘表插入一條更新記錄,根據數據庫惟一主鍵,若是數據已經存在就會報錯,而後回滾操做。
字面上理解就是多版本併發控制。是一種基於數據庫
的併發控制。咱們可讓關鍵的數據表多一個version字段。先獲取記錄值$oldVersion,而後更新的時候增長條件version=$oldVersion。用sql描述就是
select id, value1, version from table1 where id = $id; --version爲$oldVersion update table1 set value1=$newValue where id = $id and version = $oldVersion; -- 比原先id=$id 多一個version=$oldVersion條件。
這樣,代碼中就能經過判斷受影響的行數是否爲1來判斷這次更新是否成功。
這屬於一種樂觀鎖的實現。因此,通常能夠加上一些重試機制來優化用戶體驗。EFCore中的併發控制也是基於這種實現。
簡單來講鎖記錄,阻止其餘進程更新記錄,或者是讀取記錄(須要設置隔離等級)。
詳細內容等下一篇總結mysql數據庫鎖相關的內容時再說。
修改以前咱們先查一下「記錄」是否存在,若是有,就直接返回,才執行操做。這個記錄能夠是數據庫裏面的,併發量大的時候不能用,由於會出現兩個進程都讀取到不存在的狀況。這時候就須要經過redis等高速緩存來實現。由於自己redis是單線程的,全部能夠保證同一時間只有一個進程獲取到。