保證冪等性的核心思想:通過唯一的業務單號保證冪等
- 非并發情況下,查詢業務單號有沒有操作過,沒有則執行操作
- 針對第一次執行業務時間,有大量并發情況下,整個操作過程加鎖,通過分布式鎖來加鎖
- Select操作:不會對業務數據有影響,天然冪等
- Delete操作:第一次已經刪除,第二次刪除也不會有影響
- 根據唯一的業務號刪除,第一次刪除時間,已將數據刪除,第二次再次執行時間,由于找不到相應嘉璐,所以delete刪除的結果式0,對業務數據沒有影響,可在刪除前進行數據庫查詢
- 刪除操作沒有唯一業務號,則要看具體的業務需求,如刪除未審核的數據,此時多次刪除,可能會有新的未審核的數據,此時如果依然需要保證冪等性,就需要使用token機制來實現
- Update操作:更新操作傳入數據版本號,通過樂觀鎖實現冪等性
- 更新操作如果每次都是相同的值,那么不需要保證冪等性,因為值一樣
- 更新的字段的值操作是變化的,那么就會有影響,此時就是通過傳入版本號來實現
上述語句在mysql執行時間,是有行鎖的,是串行的,及時有多次提交,那么版本號不一致的情況下,也是無法完成update,即實現了冪等update set version=version+1, xxx=${xxx} where id = xxx and version = ${version}
- Insert操作:此時沒有唯一業務號的,使用Token保證冪等
- 有唯一業務號的操作,例如:秒殺場景下,商品ID+用戶ID必須是唯一的通過分布式鎖,保證并發情況下只有一個請求能夠生成記錄,然后通過數據庫的唯一索引控制數據商品ID+用戶ID只能有一條記錄,保證接口冪等,業務執行完后,不進行分布式鎖釋放,讓其過期自動釋放,重拾請求在鎖失效前,獲得不到鎖,也就失敗了
- 沒有業務號的操作,如注冊、點擊多次等,使用Token機制,保證冪等性,在進入到注冊頁時,后臺統一生成Token,返回前臺的隱藏域中。用戶提交時間,將Token一同傳入后臺使用Token作為分布式鎖的key來獲取分布式鎖,完成insert操作,執行成功后,不釋放鎖,等待過期自動釋放,拿不到分布式鎖的則無法進行操作