精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

別再讓接口亂跑!SpringBoot實現接口冪等性的四大實戰方案,徹底告別重復提交!

開發 前端
本文將帶你深入拆解?Spring Boot 實現接口冪等性的 4 種主流方案,?覆蓋從“輕量級本地防重”到“分布式高并發控制”,并結合?實戰級代碼?展示落地細節。

在分布式系統中,重復請求是最隱蔽的業務炸彈。 用戶手抖、網絡抖動、支付回調、消息隊列重試…… 任意一次“重復操作”,都有可能導致 重復扣款、重復發貨、數據異常。

本文將帶你深入拆解 Spring Boot 實現接口冪等性的 4 種主流方案, 覆蓋從“輕量級本地防重”到“分布式高并發控制”,并結合 實戰級代碼 展示落地細節。

接下來,我們將逐步拆解四大方案:

  1. Token令牌機制 —— 經典且穩
  2. 數據庫唯一索引 —— 簡潔又強一致
  3. 分布式鎖機制 —— 并發場景的核心武器
  4. 請求內容摘要 —— 最通用、最透明

Token 令牌機制:最經典的防重手段

核心思想

“先拿令牌 → 再執行業務 → 用完即焚”

通過在請求前生成一次性令牌(Token),在執行接口時驗證并原子刪除,保證每個請求只被處理一次。

代碼示例

路徑:/src/main/java/com/icoderoad/order/OrderController.java

package com.icoderoad.order;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.*;
import java.time.Duration;
import java.util.UUID;


@RestController
@RequestMapping("/order")
public class OrderController {


    @Autowired
    private StringRedisTemplate redis;


    // ① 預生成 Token,供前端使用
    @GetMapping("/token")
    public String getToken() {
        String token = UUID.randomUUID().toString();
        redis.opsForValue().set("tk:" + token, "1", Duration.ofMinutes(10));
        return token;
    }


    // ② 下單接口,Header 中攜帶令牌
    @PostMapping
    public Result create(@RequestHeader("Idempotent-Token") String token,
                         @RequestBody OrderReq req) {
        String key = "tk:" + token;
        Boolean first = redis.delete(key);
        if (Boolean.FALSE.equals(first)) {
            return Result.fail("請勿重復下單");
        }
        Order order = orderService.create(req);
        return Result.ok(order);
    }
}

要點解析:

  • UUID 生成全局唯一 Token;
  • Redis 設置 TTL(10分鐘)避免緩存堆積;
  • delete() 是原子操作,可安全防重;
  • Header 傳遞令牌,保持接口語義清晰。

數據庫唯一索引:最低成本的冪等保證

核心思想:

“唯一鍵 + 異常即冪等”

通過數據庫層面的 唯一索引,讓重復請求在插入時直接報錯,天然具備冪等特性。

代碼示例

路徑:/src/main/java/com/icoderoad/payment/PayService.java

package com.icoderoad.payment;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.stereotype.Service;


import javax.persistence.*;
import java.math.BigDecimal;


@Entity
@Table(name = "t_payment", uniqueConstraints = @UniqueConstraint(columnNames = "transaction_id"))
class Payment {
    @Id
    private Long id;


    @Column(name = "transaction_id")
    private String txId;


    private BigDecimal amount;
    private String status;
}


@Service
public class PayService {


    @Autowired
    private PaymentRepo repo;


    public Result pay(PayReq req) {
        try {
            Payment p = new Payment();
            p.setTxId(req.getTxId());
            p.setAmount(req.getAmount());
            p.setStatus("SUCCESS");
            repo.save(p);
            return Result.ok("支付成功");
        } catch (DataIntegrityViolationException e) {
            Payment exist = repo.findByTxId(req.getTxId());
            return Result.ok("已支付", exist.getId());
        }
    }
}

要點解析:

  • uniqueConstraints 確保事務級防重;
  • 異常捕獲后直接返回冪等響應;
  • 無需外部依賴,兼容老舊系統。

分布式鎖機制:高并發下的“互斥利器”

核心思想:

“對關鍵資源加鎖,誰搶到誰執行”

在并發操作中通過 Redisson 或 Zookeeper 實現互斥訪問,保障同一用戶或訂單只被處理一次。

代碼示例

路徑:/src/main/java/com/icoderoad/stock/StockService.java

package com.icoderoad.stock;


import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;


import java.util.concurrent.TimeUnit;


@Service
public class StockService {


    @Autowired
    private RedissonClient redisson;
    @Autowired
    private StockRepo repo;


    public Result deduct(DeductCmd cmd) {
        String lockKey = "lock:stock:" + cmd.getProductId();
        RLock lock = redisson.getLock(lockKey);


        try {
            if (!lock.tryLock(3, 5, TimeUnit.SECONDS)) {
                return Result.fail("處理中,請稍后");
            }
            if (repo.existsByRequestId(cmd.getRequestId())) {
                return Result.ok("已扣減");
            }
            repo.deductStock(cmd);
            return Result.ok("扣減成功");
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            return Result.fail("系統繁忙");
        } finally {
            if (lock.isHeldByCurrentThread()) {
                lock.unlock();
            }
        }
    }
}

要點解析:

  • tryLock 避免線程永久阻塞;
  • Redisson 自動續期機制防止死鎖;
  • requestId 與唯一索引配合,形成“雙保險”;
  • 適合秒殺、庫存、并發下單等高頻場景。

請求內容摘要:最透明的零侵入方案

核心思想:

“以請求內容為冪等標識,天然適配所有接口”

將請求體生成 MD5/SHA256摘要 作為冪等鍵,通過 Redis 進行原子性驗證,真正做到“客戶端無感”。

代碼示例

路徑:/src/main/java/com/icoderoad/common/aop/IdempotentAspect.java

package com.icoderoad.common.aop;


import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.DigestUtils;
import org.apache.commons.io.IOUtils;


import javax.servlet.http.HttpServletRequest;
import java.nio.charset.StandardCharsets;
import java.time.Duration;


@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Idempotent {
    int expire() default 3600; // 秒
}


@Aspect
@Component
public class IdempotentAspect {


    @Autowired
    private StringRedisTemplate redis;


    @Around("@annotation(idem)")
    public Object around(ProceedingJoinPoint pjp, Idempotent idem) throws Throwable {
        HttpServletRequest req = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String body = IOUtils.toString(req.getReader());
        String digest = DigestUtils.md5DigestAsHex(body.getBytes(StandardCharsets.UTF_8));
        String key = "idem:digest:" + digest;


        Boolean absent = redis.opsForValue().setIfAbsent(key, "1", Duration.ofSeconds(idem.expire()));
        if (Boolean.FALSE.equals(absent)) {
            return Result.fail("重復請求");
        }


        try {
            return pjp.proceed();
        } catch (Exception e) {
            redis.delete(key);
            throw e;
        }
    }
}

使用示例:

@RestController
@RequestMapping("/transfer")
public class TransferController {


    @PostMapping
    @Idempotent(expire = 7200)
    public Result transfer(@RequestBody TransferCmd cmd) {
        return Result.ok(transferSvc.doTransfer(cmd));
    }
}

要點解析:

  • 使用 MD5 壓縮請求體,確保唯一性;
  • setIfAbsent 保證 Redis 原子操作;
  • 異常回滾防止誤判;
  • 注解 + AOP 實現零侵入式冪等控制。

方案對比與落地建議

方案類型

實現復雜度

外部依賴

典型場景

Token令牌

中等

Redis

下單、支付、表單提交

唯一索引

注冊、支付回調

分布式鎖

中高

Redis/ZK

秒殺、庫存扣減

內容摘要

Redis

轉賬、接口回調

結語:冪等性不是裝飾,而是底線

冪等控制是后端架構中防止業務災難的安全閥。 選擇方案時請遵循以下三條原則:

  1. 先業務分析,再加鎖 —— 能靠唯一鍵解決的,不必上分布式鎖;
  2. 核心路徑必防重 —— 特別是支付、庫存、轉賬等資金相關接口;
  3. 冪等監控要同步上線 —— 及時發現、告警、自動恢復。

記住:冪等性不是性能開銷,而是系統穩定的基石。

從 Token 到摘要,每一種方案都有其價值, 真正的架構師,懂得“用最小的代價,守住最大的安全”。

責任編輯:武曉燕 來源: 路條編程
相關推薦

2024-06-24 01:00:00

2024-08-29 09:01:39

2023-03-03 09:11:12

高并發SpringBoot

2022-12-13 09:19:06

高并發SpringBoot

2023-03-07 08:19:16

接口冪等性SpringBoot

2024-03-13 15:18:00

接口冪等性高并發

2022-04-25 11:26:16

開發SpringBoot

2025-02-23 08:00:00

冪等性Java開發

2022-05-23 11:35:16

jiekou冪等性

2021-01-18 14:34:59

冪等性接口客戶端

2024-05-28 09:26:46

2025-07-25 01:00:00

Redis+接口冪等性

2024-11-01 09:28:02

2021-01-13 11:23:59

分布式冪等性支付

2020-07-15 08:14:12

高并發

2025-02-26 08:20:18

2025-10-20 08:00:52

2010-09-28 10:09:35

DOM對象模型

2021-03-28 09:45:05

冪等性接口數據

2020-11-12 07:43:06

Redis冪等性接口
點贊
收藏

51CTO技術棧公眾號

日韩综合一区二区| 影视先锋久久| 亚洲国产婷婷综合在线精品| 国产精品免费在线| 国产精品自拍第一页| 99久久精品国产亚洲精品| 欧美一级片在线看| 日本a级片免费观看| 麻豆网站在线看| 成人一区在线观看| 国产精品久久久久久久久久久久| 欧美卡一卡二卡三| 免费看成人吃奶视频在线| 欧美顶级少妇做爰| 日韩 欧美 高清| av免费网站在线观看| 久久亚洲一级片| 亚洲一区二区三区四区视频| 欧产日产国产69| 欧美高清一区| 伊人久久综合97精品| 亚洲少妇一区二区三区| 精品九九久久| 欧美日韩激情网| 免费久久久久久| 欧美精品久久久久久久久久丰满| 国产伦理精品不卡| 国产精品视频午夜| 亚洲s码欧洲m码国产av| 欧美二区视频| www.日韩系列| 91在线无精精品白丝| 日韩欧美在线精品| 精品久久久久久久久久久久包黑料 | 在线视频日韩欧美| 午夜精品成人av| 精品日本高清在线播放| 特级西西444| 免费观看在线黄色网| 国产日韩欧美a| 久久久久久久免费| 免费a视频在线观看| 国产美女精品一区二区三区| 国产精品专区第二| 亚洲 小说区 图片区| 美女爽到呻吟久久久久| 91豆花精品一区| 日韩欧美亚洲视频| 欧美日韩一区自拍| 欧美俄罗斯性视频| 欧美精品videos极品| 欧美96在线丨欧| 欧美成人精品在线| 天天干中文字幕| 偷偷www综合久久久久久久| 最近中文字幕mv在线一区二区三区四区| 精品人妻无码一区二区三区| 天堂99x99es久久精品免费| 亚洲国产精品女人久久久| 国产大尺度视频| 福利欧美精品在线| 亚洲国产精品成人av| 国产a√精品区二区三区四区| 日韩08精品| 日韩欧美一区二区免费| 午夜福利三级理论电影| 成人偷拍自拍| 亚洲精品xxxx| 亚欧洲乱码视频| 日韩欧美伦理| 久久亚洲春色中文字幕| 农村黄色一级片| 狠狠爱成人网| 热99在线视频| 影音先锋国产在线| 国产一区视频导航| 国产精品久久国产三级国电话系列| 内射后入在线观看一区| 97国产精品videossex| 欧美人与物videos另类| 日本中文字幕在线视频| 亚洲一区二区在线播放相泽 | 久久久久在线| 国产精品一区二区电影| 亚洲AV无码乱码国产精品牛牛| av成人免费在线| 天堂一区二区三区| 2024最新电影免费在线观看| 欧美日韩国内自拍| 色综合色综合色综合色综合| 视频二区欧美| 亚洲视频在线视频| 欧美老熟妇一区二区三区| 亚洲三级网站| 国产精品美女午夜av| 国产丝袜在线视频| 久久色在线视频| 亚洲一区精品视频| 黄毛片在线观看| 欧美日韩极品在线观看一区| 成人做爰69片免费| 欧美日韩有码| 欧美激情一区二区三区在线视频观看| 无码视频在线观看| 国产a区久久久| 五月婷婷一区| 国产盗摄——sm在线视频| 欧美日韩国产不卡| 日韩一级视频在线观看| 亚州av乱码久久精品蜜桃| 51精品在线观看| 精品黑人一区二区三区国语馆| 久久久不卡网国产精品二区| 美女av免费观看| 亚洲日本在线观看视频| 欧美videos中文字幕| 国产午夜精品久久久久久久久| 在线看片日韩| 亚洲综合色激情五月| www 日韩| 欧美日韩国产精品一区二区三区四区 | 欧美刺激午夜性久久久久久久| 91视频免费观看网站| 在线欧美日韩| 成人av免费电影| 日本三级视频在线观看| 色八戒一区二区三区| 黄色免费视频网站| 国产精品videosex极品| 成人国产精品免费视频| 波多野结衣一区二区| 色综合天天性综合| 中国一级特黄录像播放| 欧美日韩天堂| 亚洲综合成人婷婷小说| 男人在线资源站| 欧美日韩综合不卡| 日本人亚洲人jjzzjjz| 亚洲综合社区| 精品免费日产一区一区三区免费| 欧美日韩经典丝袜| 欧美一区二区三区在| 国产午夜精品理论片| 久久99久国产精品黄毛片色诱| 视频一区视频二区视频三区视频四区国产| 欧美久久天堂| 精品视频久久久久久久| 久久免费激情视频| 91丨九色丨尤物| 女人和拘做爰正片视频| 台湾佬综合网| 亲子乱一区二区三区电影| 五月天激情开心网| 日韩欧美成人免费视频| 瑟瑟视频在线观看| 老妇喷水一区二区三区| 日韩精品一线二线三线| 成人四虎影院| 日韩有码视频在线| av中文字幕观看| 亚洲成人黄色影院| 亚洲蜜桃精久久久久久久久久久久| 999亚洲国产精| 久久久com| 久久亚洲精品爱爱| 色婷婷av一区二区三区久久| 国产欧美久久久精品免费| 亚洲精品自拍动漫在线| 五月天丁香社区| 亚洲永久视频| 亚洲精品国产一区| 99tv成人影院| 久久久久久久久久久网站| 香港一级纯黄大片| 欧美性色aⅴ视频一区日韩精品| 国产午夜精品久久久久久久久| 国内成人精品2018免费看| 欧美亚洲色图视频| 亚洲激情播播| 91精品国产综合久久男男| 亚洲制服国产| 亚洲精品国产suv| 中文永久免费观看| 亚洲久草在线视频| 亚洲av综合一区二区| 久久国产精品第一页| 青青在线视频免费观看| 妖精视频一区二区三区 | 国产在线播放精品| 国产精品老女人精品视频| 亚洲wwwww| 亚洲欧美日韩国产成人| 国产欧美日韩成人| 色婷婷综合久久久久中文一区二区 | 亚洲精品亚洲人成人网在线播放| yy6080午夜| 蜜芽一区二区三区| 国产欧美日韩网站| 日本不卡电影| 激情小说网站亚洲综合网| 外国成人毛片| 国产91精品不卡视频| www久久日com| 亚洲天堂影视av| 亚洲国产精品一| 欧美三级电影网站| 69视频免费在线观看| 亚洲精品免费在线观看| 国产一区二区三区四区五区六区| 国产福利一区二区三区| 丰满少妇在线观看| 亚洲伦伦在线| 在线观看污视频| 国产一区网站| 久久本道综合色狠狠五月| 国产视频一区二| 国产精品日韩欧美综合| 蜜桃视频m3u8在线观看| 欧美激情网站在线观看| 国产精品一区二区三区视频网站| 日韩高清人体午夜| www.超碰在线.com| 在线播放中文字幕一区| 国产一卡二卡三卡| 精品国产乱码久久久久久虫虫漫画 | 欧州一区二区| 久久涩涩网站| 乱亲女h秽乱长久久久| 91国产在线播放| 亚洲ww精品| 国产精品中文字幕在线观看| av高清一区| 国产97免费视| 久久sese| 欧日韩在线观看| 精品人人视频| 91极品女神在线| 国产盗摄一区二区| 欧美激情小视频| 国产黄色大片在线观看| 欧美激情亚洲视频| 亚洲小说区图片区都市| 久青草国产97香蕉在线视频| 日本中文字幕在线视频| 精品久久久av| www.久久ai| 欧美成人免费网| 日韩av毛片| 国模精品视频一区二区| 精精国产xxxx视频在线中文版 | 亚洲色婷婷一区二区三区| 亚洲免费看黄网站| 91在线播放观看| 亚洲精品成人少妇| 国产一级视频在线播放| 亚洲成av人在线观看| 亚洲天堂日韩av| 日韩欧美在线字幕| 中文字幕日本视频| 欧美日本免费一区二区三区| 国产免费不卡视频| 欧美不卡一二三| 五月天久久久久久| 亚洲最新av在线网站| 91在线高清| 欧美精品免费在线观看| 女同视频在线观看| 4438全国成人免费| 成人影院在线免费观看| 成人在线国产精品| av成人综合| 看欧美日韩国产| 久久精品国产大片免费观看| 黄色一级片网址| 1024日韩| 黑人粗进入欧美aaaaa| 激情综合五月婷婷| 稀缺呦国内精品呦| 久久综合色之久久综合| 韩国一级黄色录像| 亚洲一区二区三区在线| 9i精品福利一区二区三区| 欧美日本视频在线| 日韩在线观看视频一区| 亚洲一区二区黄| 欧美寡妇性猛交xxx免费| 4k岛国日韩精品**专区| 亚洲成人毛片| 久久精品国产理论片免费| 久久精品国产www456c0m| 少妇人妻在线视频| 美国一区二区三区在线播放| 久久免费精品国产| 国产精品视频一区二区三区不卡| 真实国产乱子伦对白在线| 色诱视频网站一区| 国产成人av免费看| 国产亚洲精品久久久久久| 天堂亚洲精品| 国产精品久久久久久久久久三级 | 亚洲v.com| 亚洲在线观看视频| 国产精品一在线观看| 99er在线视频| 久久国产生活片100| 国产在线观看无码免费视频| 亚洲免费毛片网站| 一区二区乱子伦在线播放| 精品乱人伦小说| 爱爱爱免费视频在线观看| 欧美激情一区二区三区成人| 精品国产黄a∨片高清在线| 久久er99热精品一区二区三区| 午夜国产一区| 日韩中文字幕a| 久久九九99视频| 少妇一级淫片免费放中国| 欧美不卡123| 国产黄色在线观看| 国产精品一区二区三区在线播放| 精品中文一区| 国产免费观看高清视频| 国产成a人亚洲精| 欧美精品久久久久久久久46p| 欧美在线视频日韩| 五月婷婷狠狠干| 久久久久女教师免费一区| 亚洲一区二区三区久久久| 日韩电影大全在线观看| 美女久久网站| 精品少妇人妻一区二区黑料社区| 午夜伦理一区二区| 亚洲精品视频网| 欧美猛男性生活免费| 久久三级中文| 日本黄色播放器| 久草热8精品视频在线观看| 色婷婷国产精品免| 欧美色爱综合网| sese一区| 成人午夜激情网| 91成人免费| 婷婷中文字幕在线观看| 最近中文字幕一区二区三区| 国产三级按摩推拿按摩| 麻豆乱码国产一区二区三区| 韩国一区二区三区视频| 2021狠狠干| 懂色av一区二区三区蜜臀| 欧美日韩国产精品综合 | 国产天堂素人系列在线视频| 国产精品久久久av| 日韩精品欧美| 成人黄色一级大片| 亚洲精品中文字幕乱码三区| 性一交一乱一乱一视频| 午夜精品视频在线| 杨幂一区二区三区免费看视频| chinese少妇国语对白| 亚洲国产精品精华液2区45| 中文字幕你懂的| 久久激情视频久久| 2023国产精华国产精品| 丰满爆乳一区二区三区| 久久久亚洲高清| 91在线视频国产| 欧美人在线观看| 欧美性生活一级片| 男女污污的视频| 中文字幕一区二区三区在线不卡| 国产高清免费av| 欧美一级高清免费播放| 日本精品黄色| 中文字幕乱码在线人视频| 亚洲小说欧美激情另类| 免费在线视频你懂得| 成人精品久久一区二区三区| 欧美区亚洲区| 一本加勒比北条麻妃| 欧美日韩精品欧美日韩精品一| 日本三级韩国三级欧美三级| 久99久视频| 久久精品国产免费| www.youjizz.com亚洲| 国产午夜精品全部视频播放| 精品久久国产一区| 91视频最新入口| 亚洲欧美在线观看| 香港三日本三级少妇66| 国产在线播放不卡| 国产亚洲一区在线| 少妇被躁爽到高潮无码文| 国产视频精品一区二区三区| 成人免费91| 国产男女无遮挡| 一区二区三区欧美亚洲| 第一视频专区在线| 国产精品一区二区不卡视频| 蜜臀av一区二区三区| 五月天综合激情|