精品欧美一区二区三区在线观看 _久久久久国色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技術棧公眾號

免费成年人高清视频| 91久久大香伊蕉在人线| 中国黄色a级片| 福利一区视频| 亚洲狠狠丁香婷婷综合久久久| 国产伦精品一区二区三区| 国产无遮挡呻吟娇喘视频| 久久国产精品亚洲人一区二区三区| 久久激五月天综合精品| 日本强好片久久久久久aaa| 亚洲男人天堂手机在线| 91 视频免费观看| 电影在线观看一区| 国产精品视频观看| 久久五月天婷婷| 国产视频在线免费观看| 日韩中文字幕不卡| 久久男人资源视频| 日本一二三区在线观看| 免费视频国产一区| 亚洲精品在线免费观看视频| 日日干夜夜操s8| 免费成人在线电影| 亚洲女人的天堂| 深夜福利成人| 四虎影院在线播放| 国产91精品久久久久久久网曝门| 国产精品国语对白| 国产三级av片| 亚洲片区在线| 欧美—级高清免费播放| 五月天免费网站| 国产成人精品999在线观看| 精品美女在线观看| 亚洲欧美日韩网站| 欧美大陆国产| 欧美日本一道本在线视频| www国产精品视频| 欧美日韩喷水| 完全免费av在线播放| 欧美午夜精品理论片a级按摩| 国产69精品久久久久999小说| 成人无遮挡免费网站视频在线观看| 久久久电影一区二区三区| 极品尤物一区二区三区| 亚洲精品人妻无码| 国产经典欧美精品| 99久久自偷自偷国产精品不卡| 一区二区三区午夜| 久久99在线观看| 91免费国产视频| 国产农村妇女毛片精品| 久久精品国产精品亚洲精品| 国产精品一区二区电影| 中文天堂在线资源| 蜜桃免费网站一区二区三区| 国产精品亚洲网站| 91亚洲视频在线观看| 蜜臀久久99精品久久久久久9| 国产美女精品免费电影| 中文字幕av久久爽| 久久99精品视频| 亚洲xxxx做受欧美| 人妻妺妺窝人体色www聚色窝 | 国产精品久久国产精麻豆96堂| 日日噜噜夜夜狠狠| √天堂8在线网| 一片黄亚洲嫩模| 日韩a级在线观看| 1234区中文字幕在线观看| 午夜不卡av在线| 日本三级免费观看| 高清在线一区| 日韩欧美国产小视频| 影音先锋黄色资源| 国产成人一区| 久久久极品av| 亚洲国产综合久久| 久久一区国产| 91香蕉国产在线观看| 好吊色在线观看| 久久久精品日韩欧美| 国产精品免费一区二区三区观看| 神马久久久久| 中文字幕亚洲一区二区va在线| 五月天激情图片| 蜜桃视频www网站在线观看| 欧洲日韩一区二区三区| 欧美性猛交xx| 欧美人与物videos另类xxxxx| 中文日韩在线观看| 九九久久免费视频| 日韩国产欧美三级| 91久久久一线二线三线品牌| 欧美婷婷久久五月精品三区| 国产精品久久久久天堂| 可以在线看的av网站| 日韩中文视频| 亚洲福利视频网| 国产精品一区二区亚洲| 狠狠色综合网| 国产精品综合不卡av| 欧美 中文字幕| 中文字幕中文字幕在线一区| 国产原创popny丨九色| 99视频有精品高清视频| 亚洲精品在线视频| 欧美三级小视频| 日韩黄色小视频| 国产精品三区在线| 黄色免费在线网站| 色婷婷久久久久swag精品| 免费人成视频在线播放| 国产欧美日韩免费观看| 午夜精品久久久久久久99热浪潮| 亚洲一卡二卡在线观看| 2023国产精品视频| 无码人妻少妇伦在线电影| 伊人久久一区| 欲色天天网综合久久| 国产性猛交普通话对白| 国内成人自拍视频| 亚洲成人av动漫| 天堂√8在线中文| 精品成人一区二区三区四区| 91久久精品美女| 中文字幕在线视频一区二区三区| 欧美一区一区| 中文字幕精品一区久久久久| 亚洲第一网站在线观看| 99久久99久久免费精品蜜臀| www插插插无码免费视频网站| 24小时成人在线视频| 国产一区二区三区在线| 国产美女激情视频| 99国产精品久| 国产乱子伦农村叉叉叉| 黄色欧美在线| 久久全球大尺度高清视频| 亚洲av无码一区二区三区dv| 综合久久久久久| 亚洲小视频网站| 久久电影院7| 国产精品偷伦一区二区| 国产一二三区在线视频| 91黄色免费网站| 在线观看免费小视频| av成人毛片| 欧美lavv| 亚洲一区二区三区四区| 在线成人一区二区| 羞羞色院91蜜桃| 亚洲欧洲无码一区二区三区| 午夜xxxxx| 欧美在线黄色| 国产精品二区三区| 色是在线视频| 亚洲色图美腿丝袜| 成人黄色免费网| 日韩毛片高清在线播放| 日本成人在线免费观看| 亚洲第一网站| 老司机精品福利在线观看| 刘亦菲一区二区三区免费看| 亚洲网在线观看| 91国产精品一区| 亚洲精品视频自拍| 亚洲一区二区乱码| 日韩黄色在线观看| 久久久久亚洲av无码专区喷水| 亚洲精品黑牛一区二区三区| 久久免费成人精品视频| 每日更新在线观看av| 精品污污网站免费看| 精品国产乱码久久久久久鸭王1| 成人av高清在线| 欧美成人黑人猛交| 久久精品久久久| 精品乱色一区二区中文字幕| 日本一区二区三区视频在线| 欧美www在线| 五月婷婷综合久久| 欧美日韩一区 二区 三区 久久精品| 男女做暖暖视频| 99久久精品免费看国产 | 日本黄色录像视频| 福利电影一区二区三区| 久久久久久久久久福利| 在线观看日韩| 欧美精品一区二区三区在线四季| 在线不卡一区| 欧洲s码亚洲m码精品一区| 日本视频在线免费观看| 亚洲高清在线观看| 国产又大又长又粗| 欧美日韩亚洲一区二区| 印度午夜性春猛xxx交| 97精品久久久久中文字幕| 爱豆国产剧免费观看大全剧苏畅| 在线电影一区| aaa免费在线观看| 亚洲涩涩av| 成人国产一区二区| 久久久加勒比| 欧美一级淫片丝袜脚交| 亚洲丝袜精品| 中文国产亚洲喷潮| 日本一级在线观看| 精品久久久影院| 国产有码在线观看| 色老综合老女人久久久| 国产香蕉在线视频| 亚洲精品第1页| 国产又黄又粗视频| 91麻豆国产在线观看| 欧美69精品久久久久久不卡| 麻豆精品一二三| 欧美一级片中文字幕| 亚洲精品乱码久久久久久蜜桃麻豆| 伊人久久大香线蕉午夜av| 国产在线观看91一区二区三区 | 国产伦精品一区二区三区千人斩 | 亚洲午夜精品网| 婷婷激情四射网| 国产精品三级久久久久三级| 91中文字幕永久在线| av一二三不卡影片| 色哟哟网站在线观看| 国模少妇一区二区三区| 男女污污的视频| 日韩成人dvd| 欧美激情精品久久久久久小说| 在线视频亚洲| 男人的天堂狠狠干| 在线观看日韩av电影| 喜爱夜蒲2在线| 午夜久久tv| 毛片av在线播放| 黑丝一区二区三区| 99色这里只有精品| 亚洲精选国产| 少妇av一区二区三区无码| 99伊人成综合| 99色精品视频| 三级一区在线视频先锋| 欧美日韩在线成人| 日日噜噜夜夜狠狠视频欧美人| 成年人黄色片视频| 日韩精品一区第一页| 欧美三级理论片| 久久精品99国产精品日本| 国产无遮挡猛进猛出免费软件| 久久国产麻豆精品| 日韩av卡一卡二| 国产精品亚洲а∨天堂免在线| 午夜视频在线免费看| 成人黄色大片在线观看| 精品夜夜澡人妻无码av| 91麻豆视频网站| 午夜时刻免费入口| 中文字幕日韩欧美一区二区三区| 麻豆天美蜜桃91| 亚洲一区二区欧美日韩| 久久久久久久久影院| 在线亚洲人成电影网站色www| 探花国产精品一区二区| 欧美裸体一区二区三区| 亚洲av无码国产精品永久一区| 亚洲国产97在线精品一区| 男人av在线| 久久久精品在线观看| 123区在线| 国产成人1区| 日本视频一区在线观看| 国产精品国产三级国产在线观看| 国产 国语对白 露脸| 亚洲福利国产| 污污的网站18| 成人午夜视频在线| 蜜桃传媒一区二区亚洲| 成人欧美一区二区三区黑人麻豆| 国产一级一片免费播放| 在线免费亚洲电影| va视频在线观看| 亚洲欧美日韩国产成人| 黄色网址在线免费观看| 136fldh精品导航福利| 99只有精品| 国产精品中出一区二区三区| 精品国产中文字幕第一页| 黄色特一级视频| 视频一区二区三区中文字幕| 国产大片一区二区三区| 久久综合久久综合久久| 手机在线免费看毛片| 在线免费亚洲电影| 日本高清视频在线| 久久精品人人爽| 手机看片久久| 国产一区二区三区四区五区加勒比| 色乱码一区二区三区网站| 777av视频| 国产综合成人久久大片91| 亚洲熟妇一区二区三区| 一区二区三区四区高清精品免费观看| 国产熟妇一区二区三区四区| 精品国产乱码久久久久久免费 | 久久久久久97| 欧美性www| 日本在线免费观看一区| 黄色精品免费| 国产大片一区二区三区| 中文字幕av在线一区二区三区| 97久久久久久久| 亚洲精品一线二线三线| 97影院秋霞午夜在线观看| 国产成人精品一区| 亚洲精品无吗| 91好吊色国产欧美日韩在线| 久久国产精品免费一区二区三区| 日韩欧美卡一卡二| 精品视频一二三| 98精品国产自产在线观看| 欧美日韩黄网站| 一本—道久久a久久精品蜜桃| 日韩精品一区第一页| 日韩在线免费观看av| 欧美午夜激情小视频| 五月天婷婷视频| 97在线看福利| 欧美丝袜美腿| 六月婷婷在线视频| www.亚洲色图| 日韩av在线电影| 精品日韩欧美在线| 激情图片在线观看高清国产| 99在线视频播放| 国产精品豆花视频| 国产一精品一aⅴ一免费| 一区二区久久久久| 亚洲国产精品视频在线| 欧美日本国产在线| 日韩高清在线观看一区二区| 成人午夜免费剧场| 成人一区二区三区视频在线观看 | 亚洲自拍小视频| 亚洲国产日韩欧美在线| 久久久久无码精品| 亚洲中国最大av网站| 亚洲av片一区二区三区| 青青精品视频播放| 欧美日韩在线二区| 九九九九九国产| 亚洲免费伊人电影| 可以免费观看的毛片| 91精品国产91久久久| 色橹橹欧美在线观看视频高清| 欧美xxxxx在线视频| 欧美韩国一区二区| 99久久免费国产精精品| 欧美激情视频网| 天美av一区二区三区久久| 日本xxxxxxx免费视频| 国产精品久久久久三级| www.我爱av| 97在线免费观看视频| 成人一区二区| 手机在线免费毛片| 午夜激情一区二区三区| 黄色网址在线播放| 91精品国产自产在线老师啪| 在线精品在线| 乐播av一区二区三区| 91精品国产日韩91久久久久久| 黄色成人在线网| 日韩国产欧美精品| 国产剧情一区在线| 欧美激情亚洲综合| 最近2019中文免费高清视频观看www99 | 欧美成人精品福利| 91av亚洲| 男人的天堂视频在线| 久久伊人中文字幕| 国产区精品在线| 日韩av123| 伊人久久大香线蕉综合四虎小说| 波多野结衣有码| 欧美老人xxxx18| 黄色18在线观看| 在线免费一区| 久久综合资源网| av网站在线免费看| 国产极品精品在线观看| 综合激情在线| 成人性生交大片免费看无遮挡aⅴ| 日韩视频免费直播| 欧美大片1688网站| 女人喷潮完整视频| 亚洲久本草在线中文字幕| yw193.com尤物在线|