当前位置: 首页 > news >正文

Spring Boot中幂等性的应用

Spring Boot 中,幂等性是实现分布式系统设计和接口调用的一个重要概念,尤其在高并发、分布式环境下,确保接口重复调用不会引发系统数据异常至关重要。

幂等性概念

幂等性(Idempotence)是指一次请求和重复多次请求对系统的影响完全相同。在接口调用中,如果一个接口满足幂等性,那么无论调用多少次,最终结果是一样的。

场景分析

  1. 支付系统
    防止重复支付。例如用户多次点击支付按钮,导致重复扣款。
  2. 订单创建
    防止用户重复下单,产生多个相同订单。
  3. 短信发送
    防止重复发送短信,避免浪费资源。
  4. 库存扣减
    防止并发扣减库存,导致库存不足或超卖。
  5. 分布式任务处理
    防止任务重复执行,保证最终一致性。

如何实现幂等性

在 Spring Boot 中,常用以下几种方法实现幂等性:

1.基于数据库唯一约束

原理:
利用数据库的唯一约束机制,确保同一请求只能操作一次。

实现:

  • 在数据库表中增加一个唯一字段(如订单号、请求 ID)。
  • 插入数据时,利用唯一约束防止重复写入。

代码示例:

@Entity
@Table(name = "orders", uniqueConstraints = {@UniqueConstraint(columnNames = "orderId")})
public class Order {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;@Column(nullable = false)private String orderId; // 唯一订单号@Column(nullable = false)private BigDecimal amount;}

当重复提交时,数据库会抛出 DuplicateKeyException,可以捕获并返回提示。

2.基于唯一 Token 实现

原理:

  • 每次请求都需要携带唯一的 token,服务器校验 token 是否已使用。
  • 若已使用,则拒绝请求。

实现步骤:

1.客户端向服务器申请唯一 token(如 UUID)。

2.在请求时携带 token。

3.服务端验证 token:

  • 若 token 未使用,处理业务并标记 token 为已使用。
  • 若 token 已使用,直接返回提示。

代码示例:

@RestController
@RequestMapping("/api/order")
public class OrderController {@Autowiredprivate StringRedisTemplate redisTemplate;@PostMapping("/create")public String createOrder(@RequestParam String token) {// 校验 token 是否已存在Boolean isTokenExists = redisTemplate.opsForValue().setIfAbsent(token, "1", 10, TimeUnit.MINUTES);if (Boolean.FALSE.equals(isTokenExists)) {return "重复请求,请勿再次提交";}// 执行业务逻辑// ...return "订单创建成功";}}

优点:

  • 无需修改数据库结构。
  • 使用 Redis 提高性能,适用于高并发场景。

3.基于幂等字段校验

原理:

  • 接口请求体中包含幂等字段(如订单号、请求 ID)。
  • 服务端通过幂等字段判断请求是否已处理。

实现步骤:

  • 在业务表中增加 requestId 字段,标记唯一请求。
  • 每次请求前查询是否存在相同的 requestId。
  • 若存在,直接返回处理结果。

代码示例:

@Service
public class OrderService {@Autowiredprivate OrderRepository orderRepository;public String createOrder(String requestId, Order order) {// 校验幂等字段if (orderRepository.existsByRequestId(requestId)) {return "订单已创建,请勿重复提交";}// 保存订单order.setRequestId(requestId);orderRepository.save(order);return "订单创建成功";}}

4.基于分布式锁

原理:

  • 利用分布式锁(如 Redis 的 SETNX)对关键资源加锁,确保同一时刻只有一个请求处理。

实现步骤:

  1. 请求时加锁,锁的唯一标识为幂等字段(如订单号)。
  2. 若加锁成功,执行业务逻辑。
  3. 业务执行完成后释放锁。

代码示例:

@Service
public class SmsService {@Autowiredprivate StringRedisTemplate redisTemplate;public String sendSms(String phoneNumber) {String lockKey = "sms:lock:" + phoneNumber;// 加锁Boolean isLockAcquired = redisTemplate.opsForValue().setIfAbsent(lockKey, "1", 2, TimeUnit.MINUTES);if (Boolean.FALSE.equals(isLockAcquired)) {return "短信发送过于频繁,请稍后再试";}try {// 执行业务逻辑// ...return "短信发送成功";} finally {// 释放锁redisTemplate.delete(lockKey);}}}

5.基于状态校验

原理:

  • 根据业务状态判断请求是否重复。
  • 常用于支付、库存等有明确状态的场景。

实现步骤:

  • 增加状态字段(如订单状态、支付状态)。
  • 请求前校验状态是否已完成。

代码示例:

@Service
public class PaymentService {@Autowiredprivate OrderRepository orderRepository;public String payOrder(Long orderId) {Order order = orderRepository.findById(orderId).orElseThrow(() -> new RuntimeException("订单不存在"));// 校验状态if (order.getStatus().equals("PAID")) {return "订单已支付,请勿重复操作";}// 修改订单状态order.setStatus("PAID");orderRepository.save(order);return "支付成功";}}

幂等性设计注意事项

1.选择合适的幂等方案

  • 数据库唯一约束适合低并发场景。
  • Redis 分布式锁适合高并发场景。
  • 幂等字段校验适合需要记录请求 ID 的场景。

2.幂等字段的设计

  • 幂等字段应具有唯一性,如订单号、请求 ID。
  • 客户端生成或服务端分配均可。

3.幂等性与事务

  • 确保幂等校验与业务逻辑在同一事务中执行,避免校验通过但业务未执行完成的情况。

4.性能优化

  • 使用缓存(如 Redis)提高幂等校验性能,减少数据库压力。

总结

Spring Boot 中的幂等性实现,是确保接口安全性和数据一致性的关键。根据业务场景的不同,选择合适的幂等方案至关重要:

  • 数据库唯一约束:简单场景,直接使用。
  • Redis 分布式锁:高并发场景,提升性能。
  • 幂等字段校验:需要记录唯一请求的场景。

幂等性设计不仅是接口安全的保障,更是系统稳定性的核心体现。

相关文章:

Spring Boot中幂等性的应用

在 Spring Boot 中,幂等性是实现分布式系统设计和接口调用的一个重要概念,尤其在高并发、分布式环境下,确保接口重复调用不会引发系统数据异常至关重要。 幂等性概念 幂等性(Idempotence)是指一次请求和重复多次请求…...

【机器学习】分类

文章目录 1. 能否用回归解决分类问题2. 生成模型(概率生成)3. 判别模型(逻辑回归)4. 多分类问题 1. 能否用回归解决分类问题 二元分类 数据分布不规律,回归函数会尽量减少误差,导致不合理的偏移离分界较远…...

5.若依的角色权限控制

RBAC 基于角色的访问控制,通过角色来分配和管理用户的菜单权限。 修改课程管理的菜单到主类目下 新建角色并分配菜单 新建用户并分配角色 添加一个根菜单,父级为主类目...

Lumos学习王佩丰Excel第二十三讲:饼图美化与PPT图表

一、双坐标柱形图的补充知识 1、主次坐标设置 2、主次坐标柱形避让(通过增加两个系列,挤压使得两个柱形挨在一起) 增加两个系列 将一个系列设置成主坐标轴,另一个设成次坐标轴 调整系列位置 二、饼图美化 1、饼图美化常见设置 …...

安装winserver2008R2虚拟机步骤

一、服务器系统介绍 1.1什么是服务器? 服务器英文名称为“Server”,指的是网络环境下为客户机(Client)提供某种服务的专用计算机,服务器安装有网络操作系统(如Windows 2000 Server、Linux、Unix等)和各种服务器应用系统软件(如Web服务、电子…...

ACPI PM Timer

ACPI PM Timer 概述: ACPI PM Timer是一个非常简单的计时器,它以 3.579545 MHz 运行,在计数器溢出时生成系统控制中断(SCI)。它精度较低,建议使用其他定时器,如HPET或APIC定时器。 检测ACPI P…...

Linux 和设备树

“开放固件设备树”,简称 Devicetree (DT),是一种用于描述硬件的数据结构和语言。更具体地说,它是操作系统可读取的硬件描述,因此操作系统无需对机器的详细信息进行硬编码。 从结构上看,DT 是一棵树,或具有…...

Qt仿音乐播放器:QFileDialog添加本地文件

一、套路 QFileDialog fileDialog(this);// 创建对话框,并设置父元素;fileDialog.setWindowTitle("添加本地下载的音乐");//设置窗口标题//设置文件对话框的默认打开路径 QString projectPathQDir::currentPath();//获取当前目录 QDir dir(pr…...

Odoo 引用字段 fields.Reference:动态关系的选择器

在 Odoo 模型开发中,关系型字段是构建复杂应用的基础。 然而,传统的 m2o、o2m 和 m2m 字段需要在模型定义时就明确指定关系的目标模型,这在某些场景下会显得不够灵活。 为了解决这个问题,Odoo 提供了 fields.Reference 引用字段&a…...

Android笔试面试题AI答之Android基础(6)

Android入门请看《Android应用开发项目式教程》 文章目录 1.Android Studio版本与Gradle版本有什么关联?**1. Gradle 的作用****2. Android Studio 与 Gradle 的关系****3. 版本对应关系****4. 如何查看和修改版本****查看当前版本****修改版本** **5. 版本不兼容的…...

C# 中的记录类型简介 【代码之美系列】

🎀🎀🎀代码之美系列目录🎀🎀🎀 一、C# 命名规则规范 二、C# 代码约定规范 三、C# 参数类型约束 四、浅析 B/S 应用程序体系结构原则 五、浅析 C# Async 和 Await 六、浅析 ASP.NET Core SignalR 双工通信 …...

利用Java爬虫速卖通按关键字搜索AliExpress商品

在这个信息爆炸的时代,数据的价值日益凸显。对于电商领域的从业者来说,能够快速获取商品信息成为了一项重要的技能。速卖通(AliExpress)作为全球领先的跨境电商平台,拥有海量的商品数据。本文将介绍如何使用Java语言编…...

gitlab runner 实现 微信小程序自动化部署

微信小程序多人开发的情况下,开发人员都只能在本机上发布体验版,且需要到小程序管理后台自行切换到自己发布的版本,会出现体验版本覆盖的问题。给开发测试带来问题。 miniprogram-ci 的发布,使得开发人员可以通过命令行上传小程序…...

Playwright爬虫xpath获取技巧

示例一 <button class"MuiButtonBase-root MuiButton-root MuiLoadingButton-root MuiButton-contained MuiButton-containedPrimary MuiButton-sizeLarge MuiButton-containedSizeLarge MuiButton-colorPrimary MuiButton-fullWidth MuiButton-root MuiLoadingButton…...

总结TCP/IP四层模型

总结TCP/IP四层模型 阅读目录(Content) 一、TCP/IP参考模型概述 1.1、TCP/IP参考模型的层次结构二、TCP/IP四层功能概述 2.1、主机到网络层  2.2、网络互连层  2.3、传输层  2.3、应用层 三、TCP/IP报文格式 3.1、IP报文格式3.2、TCP数据段格式3.3、UDP数据段格式3.4、套…...

netcat和nmap的区别

Netcat 和 Nmap 是两种广泛使用的网络工具&#xff0c;但它们的功能和使用场景有所不同。下面是这两种工具的对比&#xff1a; Netcat&#xff08;nc&#xff09; 用途和功能: 网络连接: Netcat 是一个功能强大的网络工具&#xff0c;用于创建 TCP 或 UDP 连接。可以用来进行网…...

MinIO服务器文件复制(Windows环境Linux环境)

一、下载 Windows环境&#xff1a;https://dl.min.io/server/minio/release/windows-amd64/minio.exe Linux环境&#xff1a; > curl https://dl.min.io/client/mc/release/linux-amd64/mc \ --create-dirs \ -o $HOME/minio/mc > chmod x $HOME/minio/mc > expo…...

【机器学习】【朴素贝叶斯分类器】从理论到实践:朴素贝叶斯分类器在垃圾短信过滤中的应用

&#x1f31f; 关于我 &#x1f31f; 大家好呀&#xff01;&#x1f44b; 我是一名大三在读学生&#xff0c;目前对人工智能领域充满了浓厚的兴趣&#xff0c;尤其是机器学习、深度学习和自然语言处理这些酷炫的技术&#xff01;&#x1f916;&#x1f4bb; 平时我喜欢动手做实…...

无监督学习算法

K-均值聚类&#xff08;K-means clustering&#xff09;是一种常用的无监督学习算法&#xff0c;用于将数据集划分成 K 个不同的组或簇。该算法主要通过计算数据点之间的欧几里得距离来确定数据点之间的相似性&#xff0c;并根据相似性将数据点分配到不同的簇中&#xff0c;使得…...

【Compose multiplatform教程17】【组件】BoxWithConstraints组件

查看全部组件 https://blog.csdn.net/b275518834/article/details/144751353 BoxWithConstraints 功能说明&#xff1a;它是 Jetpack Compose 中的关键布局组件&#xff0c;能够精准捕捉自身所在容器的尺寸约束信息&#xff0c;通过获取最大宽度和最大高度这两个关键属性&…...

FLUX.1-dev像素模型效果展示:从草图提示词到高保真像素图全过程

FLUX.1-dev像素模型效果展示&#xff1a;从草图提示词到高保真像素图全过程 1. 像素幻梦创意工坊介绍 像素幻梦 (Pixel Dream Workshop) 是一款基于 FLUX.1-dev扩散模型构建的下一代像素艺术生成工具。它采用明亮的16-bit像素工坊视觉设计&#xff0c;为创作者提供沉浸式的AI…...

从nvidia-smi到npu-smi:给CUDA开发者的华为昇腾NPU监控指南

从nvidia-smi到npu-smi&#xff1a;CUDA开发者快速掌握昇腾NPU监控的实战手册 当你的技术栈从英伟达GPU扩展到华为昇腾NPU时&#xff0c;监控工具的使用体验就像从自动挡切换到手动挡——虽然最终目的地相同&#xff0c;但操作逻辑需要重新适应。作为曾经每天与nvidia-smi打交道…...

纯本地运行!AgentCPM深度研报助手,手把手教你离线生成研究报告

纯本地运行&#xff01;AgentCPM深度研报助手&#xff0c;手把手教你离线生成研究报告 1. 为什么选择本地研报生成工具&#xff1f; 在信息爆炸的时代&#xff0c;专业研究报告的撰写面临三大痛点&#xff1a; 时间压力&#xff1a;从零开始撰写一份深度报告平均需要40-60小…...

实践指南:借助LLaMa-Factory高效定制你的专属LLaMa3

1. 为什么选择LLaMa-Factory微调LLaMa3&#xff1f; 第一次尝试微调大语言模型时&#xff0c;我花了整整三天时间在环境配置上。从CUDA版本冲突到PyTorch依赖问题&#xff0c;各种报错让人崩溃。直到发现LLaMa-Factory这个"微调瑞士军刀"&#xff0c;才明白原来大模型…...

OpenClaw多任务测试:nanobot镜像并行处理能力评估

OpenClaw多任务测试&#xff1a;nanobot镜像并行处理能力评估 1. 测试背景与目标 最近在探索OpenClaw的自动化能力边界时&#xff0c;我遇到了一个实际需求&#xff1a;能否让这个智能体框架同时处理多个不同类型的任务&#xff1f;比如一边整理本地文件&#xff0c;一边抓取…...

绕过RK3588的RGA坑:手把手教你修改YOLOv8分割模型部署代码,用CPU预处理替代硬件加速

RK3588部署YOLOv8分割模型的稳定化实践&#xff1a;从RGA报错到CPU预处理方案优化 当你在RK3588开发板上部署YOLOv8分割模型时&#xff0c;是否遇到过这样的场景&#xff1a;模型转换和交叉编译一切顺利&#xff0c;却在运行时突然弹出"Failed to call RockChipRga interf…...

单细胞测序数据读取实战指南:从CellRanger到Seurat对象

1. 单细胞测序数据读取入门指南 第一次接触单细胞测序数据分析时&#xff0c;最让人头疼的就是数据读取环节。记得我刚入门那会儿&#xff0c;光是理解CellRanger输出的各种文件格式就花了整整一周时间。不过别担心&#xff0c;今天我就把这块硬骨头啃碎了讲给你听。 单细胞测序…...

从‘米勒平台’到‘零电压开关’:深入浅出聊聊MOS管栅极驱动的那些门道与进阶玩法

从‘米勒平台’到‘零电压开关’&#xff1a;深入浅出聊聊MOS管栅极驱动的那些门道与进阶玩法 在功率电子领域&#xff0c;MOS管的开关过程就像一场精密的芭蕾舞表演&#xff0c;而栅极驱动则是那位看不见的编舞师。当您第一次在示波器上观察到那个神秘的"米勒平台"时…...

PCU9669 LED驱动库:Mini Board嵌入式快速验证方案

1. 项目概述utility库是为 Mini Board PCU9669 评估套件&#xff08;Evaluation Kit&#xff09;配套开发的底层驱动与功能封装库&#xff0c;专为快速验证 NXP PCU9669 高精度、多通道 LED 驱动与电流/电压监控芯片而设计。该库并非通用型 HAL 抽象层&#xff0c;而是面向特定…...

用Python玩转Iris数据集:从数据加载到可视化分析的完整指南

用Python玩转Iris数据集&#xff1a;从数据加载到可视化分析的完整指南 鸢尾花数据集&#xff08;Iris dataset&#xff09;是机器学习领域最经典的数据集之一&#xff0c;它就像编程界的"Hello World"&#xff0c;是每个数据科学初学者必学的案例。这个数据集不仅结…...