当前位置: 首页 > 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;通过获取最大宽度和最大高度这两个关键属性&…...

HTML 语义化

目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案&#xff1a; 语义化标签&#xff1a; <header>&#xff1a;页头<nav>&#xff1a;导航<main>&#xff1a;主要内容<article>&#x…...

抖音增长新引擎:品融电商,一站式全案代运营领跑者

抖音增长新引擎&#xff1a;品融电商&#xff0c;一站式全案代运营领跑者 在抖音这个日活超7亿的流量汪洋中&#xff0c;品牌如何破浪前行&#xff1f;自建团队成本高、效果难控&#xff1b;碎片化运营又难成合力——这正是许多企业面临的增长困局。品融电商以「抖音全案代运营…...

(二)原型模式

原型的功能是将一个已经存在的对象作为源目标,其余对象都是通过这个源目标创建。发挥复制的作用就是原型模式的核心思想。 一、源型模式的定义 原型模式是指第二次创建对象可以通过复制已经存在的原型对象来实现,忽略对象创建过程中的其它细节。 📌 核心特点: 避免重复初…...

汇编常见指令

汇编常见指令 一、数据传送指令 指令功能示例说明MOV数据传送MOV EAX, 10将立即数 10 送入 EAXMOV [EBX], EAX将 EAX 值存入 EBX 指向的内存LEA加载有效地址LEA EAX, [EBX4]将 EBX4 的地址存入 EAX&#xff08;不访问内存&#xff09;XCHG交换数据XCHG EAX, EBX交换 EAX 和 EB…...

uniapp中使用aixos 报错

问题&#xff1a; 在uniapp中使用aixos&#xff0c;运行后报如下错误&#xff1a; AxiosError: There is no suitable adapter to dispatch the request since : - adapter xhr is not supported by the environment - adapter http is not available in the build 解决方案&…...

爬虫基础学习day2

# 爬虫设计领域 工商&#xff1a;企查查、天眼查短视频&#xff1a;抖音、快手、西瓜 ---> 飞瓜电商&#xff1a;京东、淘宝、聚美优品、亚马逊 ---> 分析店铺经营决策标题、排名航空&#xff1a;抓取所有航空公司价格 ---> 去哪儿自媒体&#xff1a;采集自媒体数据进…...

代理篇12|深入理解 Vite中的Proxy接口代理配置

在前端开发中,常常会遇到 跨域请求接口 的情况。为了解决这个问题,Vite 和 Webpack 都提供了 proxy 代理功能,用于将本地开发请求转发到后端服务器。 什么是代理(proxy)? 代理是在开发过程中,前端项目通过开发服务器,将指定的请求“转发”到真实的后端服务器,从而绕…...

Spring是如何解决Bean的循环依赖:三级缓存机制

1、什么是 Bean 的循环依赖 在 Spring框架中,Bean 的循环依赖是指多个 Bean 之间‌互相持有对方引用‌,形成闭环依赖关系的现象。 多个 Bean 的依赖关系构成环形链路,例如: 双向依赖:Bean A 依赖 Bean B,同时 Bean B 也依赖 Bean A(A↔B)。链条循环: Bean A → Bean…...

20个超级好用的 CSS 动画库

分享 20 个最佳 CSS 动画库。 它们中的大多数将生成纯 CSS 代码&#xff0c;而不需要任何外部库。 1.Animate.css 一个开箱即用型的跨浏览器动画库&#xff0c;可供你在项目中使用。 2.Magic Animations CSS3 一组简单的动画&#xff0c;可以包含在你的网页或应用项目中。 3.An…...

【电力电子】基于STM32F103C8T6单片机双极性SPWM逆变(硬件篇)

本项目是基于 STM32F103C8T6 微控制器的 SPWM(正弦脉宽调制)电源模块,能够生成可调频率和幅值的正弦波交流电源输出。该项目适用于逆变器、UPS电源、变频器等应用场景。 供电电源 输入电压采集 上图为本设计的电源电路,图中 D1 为二极管, 其目的是防止正负极电源反接, …...