最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

淺談java接口的冪等性及解決方案

 更新時間:2021年11月08日 10:03:32   作者:yuec1998  
本文主要介紹了java接口的冪等性及解決方案,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下

一、什么情況下需要冪等

用戶多次點擊按鈕
用戶頁面回退再次提交
微服務相互調用,由于網(wǎng)絡問題,導致請求失敗,feign觸發(fā)重試機制

二、冪等性解決方案

2.1 token機制(令牌)

在加載頁面詳情時候,服務器會順便生成一個token一起返回給前端,服務端同時也在Redis中保存這個token數(shù)據(jù),前端并不展示這個token,但當頁面點擊提交按鈕時候,會在攜帶上這個token參數(shù),此時后端便會先校驗前端提交請求的token與redis中的token是否一致,一致的話即是第一次請求,執(zhí)行業(yè)務代碼并在Redis中刪除該token,當用戶還是攜帶上次的驗證碼多次提交,此時服務器判斷redis中驗證碼不存在,便可能是多次提交的情況,不再執(zhí)行業(yè)務代碼,保證業(yè)務的冪等性,不被重復執(zhí)行。

問題1:先刪除token還是后刪除token

先刪除可能導致, 業(yè)務確實沒有執(zhí)行,重試還帶上之前token,由于防重設計導致,請求還是不能執(zhí)行。后刪除可能導致,業(yè)務處理成功,但是服務閃斷,出現(xiàn)超時,沒有刪除token,別人繼續(xù)重試,導致業(yè)務被執(zhí)行兩遍
解決:我們最好設計為先刪除token,如果業(yè)務調用失敗,就重新獲取token再次請求。

問題2:如何保證token 獲取、比較和刪除必須是原子性

redis.get(token) 、token.equals、 redis del(token)如果這兩個操作不是原子,可能導致,高并發(fā)下,都get到同樣的數(shù)據(jù),判斷都成功,繼續(xù)業(yè)務并發(fā)執(zhí)行

解決:可以在redis使用lua腳本完成這個操作

//  redis+lua腳本 原子驗證令牌防止重復提交攻擊
        String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
        String orderToken = "現(xiàn)在的令牌";
        //  return 0 失敗  1 成功
        Long result = stringRedisTemplate.execute(new DefaultRedisScript<Long>(script, Long.class),Arrays.asList("要驗證的KEY"), orderToken);

2.2 各種鎖機制

1)數(shù)據(jù)庫悲觀鎖

//0.開始事務
begin;
//1.查詢出商品信息
select status from t_goods where id=1 for update;
//2.根據(jù)商品信息生成訂單
insert into t_orders (id,goods_id) values (null,1);
//3.修改商品status為2
update t_goods set status=2;
//4.提交事務
commit;

2)數(shù)據(jù)庫樂觀鎖
適用讀多寫少的情況

update t_goods set status=2,version=version+1 where id=#{id} and version=#{version};

3)業(yè)務層分布式鎖
redison可以解決,代碼實現(xiàn)

    @Override
    @RedisLock(lockedPrefix = "model:replace:materialId:", timeOut = 5000)
    @Transactional(rollbackFor = Exception.class)
    public void changeSpuSync(@LockedObject Integer materialId, String userName) {
        log.info("模型表監(jiān)聽物料檔案id={}是否修改了spu", materialId);
        ModelChangeSpuReq modelChangeSpuReq = new ModelChangeSpuReq(materialId, userName);
        this.dealChangeSpuSyncModel(modelChangeSpuReq);
    }

2.3 各種唯一約束

1)數(shù)據(jù)庫的唯一約束:
利用主鍵的唯一性
2)redis set防重:
很多數(shù)據(jù)需要處理,只能被處理一次,比如我們可以計算數(shù)據(jù)的MD5將其放入redis的set,每次處理數(shù)據(jù),先看這個MD5是否已經(jīng)存在,存在就不處理。(百度上傳文件秒傳機制,如果該文件已經(jīng)存在,就無需重復上傳)

2.4 防重表

使用訂單號orderNo做為去重表的唯一索引, 把唯一索引插入去重表, 再進行業(yè)務操作,且他們在同一個事中。這個保證了重復請求時,因為去重表有唯一約束,導致請求失敗,避免了冪等問題。這里要注意的是,去重表和業(yè)務表應該在同一庫中,這樣就保證了在同一個事務,即使業(yè)務操作失敗了,也會把去重表的數(shù)據(jù)回滾。這個很好的保證了數(shù)據(jù)一致性。

2.5 全局請求唯一id

前端每次調用接口請求時,生成一個唯一id,redis將數(shù)據(jù)保存到集合中(去重),存在即處理過。
全鏈路tranceId:可以使用Nginx設置每一個請求的唯一id;也可方便系統(tǒng)的鏈路追蹤,該id并不能解決去重問題,當A系統(tǒng)調用B系統(tǒng),B系統(tǒng)是否產(chǎn)生重試機制時候,可以根據(jù)這個id去判斷

proxy_set header X-Request-ld $request_id;

總結

總之,一般情況下,幾種方式的優(yōu)選級使用順序可以這樣:分布式鎖 > 樂觀鎖 > JVM鎖 > 唯一約束 > 數(shù)據(jù)庫悲觀鎖

當然,冪等性設計不能脫離業(yè)務實際來討論,一定要根據(jù)實際業(yè)務場景選擇合適的冪等性解決方案。

到此這篇關于淺談java接口的冪等性及解決方案的文章就介紹到這了,更多相關java接口的冪等性內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • 淺談synchronized加鎖this和class的區(qū)別

    淺談synchronized加鎖this和class的區(qū)別

    synchronized 是 Java 語言中處理并發(fā)問題的一種常用手段,本文主要介紹了synchronized加鎖this和class的區(qū)別,具有一定的參考價值,感興趣的可以了解一下
    2021-11-11
  • RabbitMQ簡單隊列實例及原理解析

    RabbitMQ簡單隊列實例及原理解析

    這篇文章主要介紹了RabbitMQ簡單隊列實例及原理解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-12-12
  • 如何在java 8 map中使用stream

    如何在java 8 map中使用stream

    這篇文章主要介紹了如何在java 8 map中使用stream,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-04-04
  • java 實現(xiàn)通過 post 方式提交json參數(shù)操作

    java 實現(xiàn)通過 post 方式提交json參數(shù)操作

    這篇文章主要介紹了java 實現(xiàn)通過 post 方式提交json參數(shù)操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-09-09
  • Spring?Boot深入排查?java.lang.ArrayStoreException異常

    Spring?Boot深入排查?java.lang.ArrayStoreException異常

    這篇文章介紹了Spring?Boot深入排查?java.lang.ArrayStoreException異常,文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-12-12
  • Springboot熱部署實現(xiàn)原理及實例詳解

    Springboot熱部署實現(xiàn)原理及實例詳解

    這篇文章主要介紹了Springboot熱部署實現(xiàn)原理及實例詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-05-05
  • Java語法基礎之for語句練習

    Java語法基礎之for語句練習

    以下是對Java語法基礎中的for語句進行了詳細介紹,需要的朋友可以過來參考下
    2013-07-07
  • 簡單了解Java編程中對異常處理的運用

    簡單了解Java編程中對異常處理的運用

    這篇文章主要簡單介紹了Java編程中對異常處理的運用,是Java入門學習中的基礎知識,需要的朋友可以參考下
    2015-09-09
  • SpringBoot實現(xiàn)配置文件加密的方案分享

    SpringBoot實現(xiàn)配置文件加密的方案分享

    項目的數(shù)據(jù)庫密碼、redis 密碼等明文展示在配置文件中會有潛在的風險,因此采用合適的安全防護措施是有必要的,下面小編就為大家介紹一下SpringBoot中配置文件加密的方法,希望對大家有所幫助
    2023-11-11
  • SpringBoot 策略模式實現(xiàn)切換上傳文件模式

    SpringBoot 策略模式實現(xiàn)切換上傳文件模式

    策略模式是指有一定行動內(nèi)容的相對穩(wěn)定的策略名稱,這篇文章主要介紹了SpringBoot 策略模式 切換上傳文件模式,需要的朋友可以參考下
    2023-11-11

最新評論

荃湾区| 辉县市| 江北区| 巴林右旗| 靖边县| 如东县| 河源市| 富民县| 永兴县| 清丰县| 浙江省| 渑池县| 忻州市| 盘山县| 民乐县| 巴中市| 望城县| 桐庐县| 广东省| 扎兰屯市| 拉萨市| 南漳县| 满洲里市| 青川县| 和龙市| 绿春县| 长治市| 化德县| 东阿县| 博白县| 宣化县| 宜兴市| 炎陵县| 江都市| 淳化县| 赣榆县| 张家口市| 大新县| 嘉善县| 开封县| 旌德县|