spring boot实现接口幂等性操作

SpringBoot 接口实现幂等性,我有四种方案! 1、目录什么是幂等性什么是接口幂等性为什么需要实现幂等性引入幂等性后对系统的影响Restful API 接口的幂等性如何实现幂等性方案一:数据库唯一主键方案二:数据库乐观锁方案三:防重 Token 令牌方案四、下游传递唯一序列号实现接口示例Maven 引入相关依赖配置连接 Redis 的参数创建与验证 Token 工具类创建测试的 Controller 类创建 SpringBoot 启动类写测试类进行测试最后总结Java JDK 版本:1.8。 阅读详情

前言:

在实际的开发项目中,一个对外暴露的接口往往会面临很多次请求,我们来解释一下幂等的概念:任意多次执行所产生的影响均与一次执行的影响相同。按照这个含义,最终的含义就是 对数据库的影响只能是一次性的,不能重复处理。如何保证其幂等性,通常有以下手段:

  • 数据库建立唯一性索引,可以保证最终插入数据库的只有一条数据
  • token机制,每次接口请求前先获取一个token,然后再下次请求的时候在请求的header体中加上这个token,后台进行验证,如果验证通过删除token,下次请求再次判断token
  • 悲观锁或者乐观锁,悲观锁可以保证每次for update的时候其他sql无法update数据(在数据库引擎是innodb的时候,select的条件必须是唯一索引,防止锁全表)
  • 先查询后判断,首先通过查询数据库是否存在数据,如果存在证明已经请求过了,直接拒绝该请求,如果没有存在,就证明是第一次进来,直接放行。

原理图:
redis实现自动幂等的原理图:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ofu2yRgw-1613960840522)(en-resource://database/1097:1)]

1.新建redis工具类

package com.cyc.quick.util;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;

import java.io.Serializable;
import java.util.concurrent.TimeUnit;

/**
 * redis工具类
 * @author fei
 */
@Component
public class RedisUtil {

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 写入缓存
     * @param key
     * @param value
     * @return
     */
    public boolean set(final String key, Object value) {
        boolean result = false;
        try {
            ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
            operations.set(key, value);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }


    /**
     * 写入缓存设置时效时间
     * @param key
     * @param value
     * @return
     */
    public boolean setEx(final String key, Object value, Long expireTime) {
        boolean result = false;
        try {
            ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
            operations.set(key, value);
            redisTemplate.expire(key, expireTime, TimeUnit.SECONDS);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }


    /**
     * 判断缓存中是否有对应的value
     * @param key
     * @return
     */
    public boolean exists(final String key) {
        return redisTemplate.hasKey(key);
    }

    /**
     * 读取缓存
     * @param key
     * @return
     */
    public Object get(final String key) {
        Object result = null;
        ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
        result = operations.get(key);
        return result;
    }

    /**
     * 删除对应的value
     * @param key
     */
    public boolean remove(final String key) {
        if (exists(key)) {
            Boolean delete = redisTemplate.delete(key);
            return delete;
        }
        return false;

    }

}

2. 自定义注解AutoIdempotent

自定义一个注解,定义此注解的主要目的是把它添加在需要实现幂等的方法上,凡是某个方法注解了它,都会实现自动幂等。后台利用反射如果扫描到这个注解,就会处理这个方法实现自动幂等,使用元注解ElementType.METHOD表示它只能放在方法上,etentionPolicy.RUNTIME表示它在运行时

package com.cyc.quick.ann;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * @description 自定义注解-实现幂等性校验, 用在方法上
 * @author fei
 */
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface AutoIdempotent {
  
}

3. token创建和检验

3.1 token服务接口

我们新建一个接口,创建token服务,里面主要是两个方法,一个用来创建token,一个用来验证token。创建token主要产生的是一个字符串,检验token的话主要是传达request对象,为什么要传request对象呢?主要作用就是获取header里面的token,然后检验,通过抛出的Exception来获取具体的报错信息返回给前端

package com.cyc.quick.token;

import javax.servlet.http.HttpServletRequest;

public interface TokenService {

    /**
     * 创建token
     * @return
     */
    String createToken();

    /**
     * 检验token
     * @param request
     * @return
     */
    boolean checkToken(HttpServletRequest request) throws Exception;

}

3.2 token的服务实现类

token引用了redis服务,创建token采用随机算法工具类生成随机uuid字符串,然后放入到redis中(为了防止数据的冗余保留,这里设置过期时间为10000秒,具体可视业务而定),如果放入成功,最后返回这个token值。checkToken方法就是从header中获取token到值(如果header中拿不到,就从paramter中获取),如若不存在,直接抛出异常。这个异常信息可以被拦截器捕捉到,然后返回给前端

package com.cyc.quick.token;

import cn.hutool.core.text.StrBuilder;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.cyc.quick.constants.Constant;
import com.cyc.quick.exception.ProjectException;
import com.cyc.quick.util.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;

/**
 * @author fei
 */
@Service
@Slf4j
public class TokenServiceImpl implements TokenService {

    @Autowired
    private RedisUtil redisUtil;


    /**
     * 创建token
     *
     * @return token
     */
    @Override
    public String createToken() {
        String token = RandomUtil.randomString(20);
        StrBuilder redisToken = new StrBuilder();
        try {
            redisToken.append(Constant.Redis.TOKEN_PREFIX).append(token);
            redisUtil.setEx(redisToken.toString(), token, 10000L);
            boolean notEmpty = StrUtil.isNotEmpty(token);
            if (notEmpty) {
                return token;
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return null;
    }


    /**
     * 检验token
     *
     * @param request 请求request
     */
    @Override
    public boolean checkToken(HttpServletRequest request) {

        String token = request.getHeader(Constant.TOKEN_NAME);
        if (StrUtil.isBlank(token)) {
            // header中不存在token
            token = request.getParameter(Constant.TOKEN_NAME);
            if (StrUtil.isBlank(token)) {
                // parameter中也不存在token
                throw new ProjectException("100", "非法访问,缺少token");
            }
        }

        if (!redisUtil.exists(Constant.Redis.TOKEN_PREFIX + token)) {
            log.info("重复访问或token错误");
            throw new ProjectException("200", "请勿重复点击");
        }
        //访问成功后, 删除redis中该token ,
        boolean remove = redisUtil.remove(Constant.Redis.TOKEN_PREFIX + token);
        if (!remove) {
            throw new ProjectException("200", "移除token失败");
        }
        return true;
    }
}

4. 配置拦截器

4.1 web配置类

实现WebMvcConfigurerAdapter,主要作用就是添加autoIdempotentInterceptor到配置类中,这样我们到拦截器才能生效,注意使用@Configuration注解,这样在容器启动是时候就可以添加进入context中

package com.cyc.quick.config;

import cn.hutool.json.JSONUtil;
import com.cyc.quick.ann.AutoIdempotent;
import com.cyc.quick.exception.ProjectException;
import com.cyc.quick.token.TokenService;
import com.cyc.quick.util.ApiResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.Method;

/**
 * 拦截器
 *
 * @author fei
 */
@Component
@Slf4j
public class AutoIdempotentInterceptor implements HandlerInterceptor {

    @Autowired
    private TokenService tokenService;

    /**
     * 预处理
     *
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        if (!(handler instanceof HandlerMethod)) {
            return true;
        }
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        Method method = handlerMethod.getMethod();
        //被ApiIdempotment标记的扫描
        AutoIdempotent methodAnnotation = method.getAnnotation(AutoIdempotent.class);
        if (methodAnnotation != null) {
            try {
                // 幂等性校验, 校验通过则放行, 校验失败则抛出异常, 并通过统一异常处理返回友好提示
                return tokenService.checkToken(request);
            } catch (Exception ex) {
                ApiResult failedResult;
                log.info("访问被拦截的原因为: {}", ex.getMessage());
                if (ex instanceof ProjectException) {
                    failedResult = ApiResult.error(((ProjectException) ex).getStatus(), ex.getMessage());
                    writeReturnJson(response, JSONUtil.toJsonStr(failedResult));
                } else {
                    failedResult = ApiResult.error("500", ex.getMessage());
                    writeReturnJson(response, JSONUtil.toJsonStr(failedResult));
                    throw ex;
                }
                return false;
            }
        }
        //必须返回true,否则会被拦截一切请求
        return true;
    }


    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

    }

    /**
     * 返回的json值
     *
     * @param response
     * @param json
     * @throws Exception
     */
    private void writeReturnJson(HttpServletResponse response, String json) throws Exception {
        PrintWriter writer = null;
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html; charset=utf-8");
        try {
            writer = response.getWriter();
            writer.print(json);

        } catch (IOException e) {
        } finally {
            if (writer != null) {
                writer.close();
            }
        }
    }

}

4.2 拦截处理器

主要的功能是拦截扫描到AutoIdempotent到注解到方法,然后调用tokenService的checkToken()方法校验token是否正确,如果捕捉到异常就将异常信息渲染成json返回给前端

package com.cyc.quick.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

import javax.annotation.Resource;

@Configuration
public class WebConfiguration implements WebMvcConfigurer {

    @Resource
    private AutoIdempotentInterceptor autoIdempotentInterceptor;

    /**
     * 添加拦截器
     *
     * @param registry
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(autoIdempotentInterceptor);
    }
}

5.测试

1:模拟业务请求类
首先我们需要通过/get/token路径通过getToken()方法去获取具体的token,然后我们调用testIdempotence方法,这个方法上面注解了@AutoIdempotent,拦截器会拦截所有的请求,当判断到处理的方法上面有该注解的时候,就会调用TokenService中的checkToken()方法,如果捕获到异常会将异常抛出调用者,下面我们来模拟请求一下:

package com.cyc.quick.controller;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.cyc.quick.ann.AutoIdempotent;
import com.cyc.quick.service.TestService;
import com.cyc.quick.token.TokenService;
import com.cyc.quick.util.ApiResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

/**
 * @author fei
 * 测试接口幂等性
 */
@RestController
@RequestMapping("/test")
@Api(tags = "测试类")
public class TestController {


    @Resource
    private TokenService tokenService;

    @Resource
    private TestService testService;


    @GetMapping("/getToken")
    @ApiOperation("获取token")
    public ApiResult getToken() {
        String token = tokenService.createToken();
        return ApiResult.success(token);
    }


    @AutoIdempotent
    @PostMapping("/idempotence")
    @ApiOperation("测试接口幂等性")
    public ApiResult testIdempotence() {
        String businessResult = testService.testIdempotence();
        if (StrUtil.isNotEmpty(businessResult)) {
            return ApiResult.success();
        }
        return ApiResult.error("200","系统错误");
    }
}
  1. 查看结果
    获取token

在这里插入图片描述

3.携带token进行访问
在这里插入图片描述

第二次访问显示失败
再多次请求到时候我们只让其第一次成功,第二次就是失败:
在这里插入图片描述

后台日志

在这里插入图片描述

6.总结

使用springboot和拦截器、redis来优雅的实现接口幂等,对于幂等在实际的开发过程中是十分重要的,因为一个接口可能会被无数的客户端调用,如何保证其不影响后台的业务处理,如何保证其只影响数据一次是非常重要的,它可以防止产生脏数据或者乱数据,也可以减少并发量,实乃十分有益的一件事。而传统的做法是每次判断数据,这种做法不够智能化和自动化,比较麻烦。而今天的这种自动化处理也可以提升程序的伸缩性。

代码地址

SpringBoot第19讲:SpringBoot 如何保证接口幂等 幂等原先是数学中的一个概念,表示进行1次变换和进行N次变换产生的效果相同。以相同的请求调用这个接口一次和调用这个接口多次,对系统产生的影响是相同的。如果一个接口满足这个特性,那么我们就说这个接口是一个幂等接口。接口幂等和防止重复提交是一回事吗?严格来说,并不是。幂等: 更多的是在重复请求已经发生,或是无法避免的情况下,采取一定的技术手段让这些重复请求不给系统带来副作用。防止重复: 提交更多的是不让用户发起多次一样的请求。 阅读详情

相关推荐

Spring Boot接口幂等性保卫战:4大绝招+代码详解,重复请求秒变‘哑炮’!

幂等性就像‘时间暂停术’——无论请求多少次,结果都像只执行了一次!没有它,你的系统可能被重复请求‘打成筛子’!用Token+Redis+数据库唯一索引‘三重防护’,让重复请求‘三连跪’!“用版本号玩‘竞速游戏’,更新时比对版本,旧版本直接‘淘汰’!“生成唯一令牌,存Redis+过期时间,像‘魔法通行证’!“用AOP和自定义注解,像‘念咒语’一样优雅实现幂等性,代码侵入性降低90%!“用数据库唯一约束当‘钢铁锁链’,重复插入直接报错!原子操作,让令牌校验‘一步到位’!🔥关注墨瑾轩,带你探索编程的奥秘!

java专栏 858

SpringBoot如何保证接口的幂等性?六种方案一次讲清楚~

在计算机领域中,幂等(Idempotence)是指任意一个操作的多次执行总是能获得相同的结果,不会对系统状态产生额外影响。在Java后端开发中,幂等性的实现通常通过确保方法或服务调用的结果具有确定性,无论调用次数如何,结果都是可预期的。上面的定义是目前大多数文章和书籍对幂等的描述,然而,在实际的互联网服务开发中,幂等性的理论定义与业务逻辑间的冲突是常见的。

竹林幽深 1539

【星火】海思HI3516C开发板实战:基于LVGL与MPP库的行车记录仪/电子显微镜方案

本文详细介绍了基于海思HI3516CV500开发板,结合LVGL图形库与海思MPP媒体处理平台,实现行车记录仪与电子显微镜方案的完整实战过程。内容涵盖从系统环境搭建、驱动配置到应用开发的全流程,重点解析了MPP视频流处理管道与LVGUI界面协同工作的核心机制,为嵌入式音视频开发提供了可复用的参考方案。

weixin_42126677的博客 160

基于SpringBoot实现Api接口幂等性的几种方式

接口幂等性,token方式实现接口幂等性,redis + lua脚本实现接口幂等性

qq_35267557的博客 2234

macOS Monterey官方镜像高速下载指南(附迅雷链接+兼容性清单)

本文提供macOS Monterey官方镜像的高速下载指南,重点介绍利用迅雷等工具加速下载官方安装包的有效方法。同时,详细列出了系统兼容性清单,帮助用户在下载前确认设备支持,并分享了从下载、验证到安全安装的完整流程与常见问题解决方案。

j7k8l的博客 2166

Proteus 8.15仿真STM32F103C8,ADC采样总为0?别急着换芯片,先检查这3个配置

本文详细解析了在Proteus 8.15中仿真STM32F103C8时ADC采样值为0的常见原因及解决方法。从供电网络配置、时钟设置到ADC参数调整,提供了系统性的排查指南,帮助开发者快速定位问题,避免不必要的硬件更换。重点关注供电网络、时钟分频和ADC配置等关键环节。

weixin_30425949的博客 366

springboot 接口幂等

springboot 接口幂等

weixin_43931625的博客 712

DSP28335与Vofa+上位机通信实战:SCIb配置避坑指南(附完整代码)

本文提供DSP28335与Vofa+上位机通信的实战指南,重点解析SCIb模块配置的常见问题与解决方案。针对研旭开发板的硬件连接、波特率精确计算、FIFO高效使用以及FireWater协议封装进行了详细说明,并附有完整代码,帮助开发者快速实现实时数据可视化与波形分析,提升调试效率。

weixin_29172963的博客 149

太好了 | 这篇写的太好了!Spring Boot + Redis 实现接口幂等性

Hi ! 我是小小,今天是本周的第四篇,第四篇主要内容是 Spring Boot + Redis 实现接口幂等性介绍幂等性的概念是,任意多次执行所产生的影响都与一次执行产生的影响相同,按...

mySoul 8025

8.5华为OD机试真题 新系统 - IPv4 等长子网划分与自动分配系统 (Java/Py/C/C++/Js/Go)

8.5华为OD机试真题 新系统 - IPv4 等长子网划分与自动分配系统 (Java/Py/C/C++/Js/Go)

算法大师! 524

【33】软考软件设计师——算法题(二):贪心法与回溯法深度精讲|第4题进阶满分攻略

本文是《软件设计师·50讲通关|从零基础到工程师职称》专栏第33篇,承接第32篇分治法与动态规划,聚焦**下午第4题算法大题进阶核心**,详解贪心法与回溯法两大高频难点算法。全文超4000字深度拆解贪心法核心原理、贪心选择性质、局部最优推全局最优的底层逻辑,厘清贪心算法适用边界与经典误区;深挖回溯法深度优先遍历思想、递归回溯三步流程、可行性剪枝与最优性剪枝两大核心技巧;全覆盖活动选择、零钱兑换、01背包贪心禁区、八皇后、全排列等软考必考经典题型;配套标准化算法框架代码、考场填空模板、剪枝优化实操案例

专注于人工智能、软件开发、工控自动化、工厂数字化及智能化等领域,希望和大家共同进步! 438

Redis处理 Spring Boot 接口幂等性【使用拦截器处理版本】

接口幂等性就是用户对于同一操作发起的一次请求或者多次请求的结果是一致的,不会因为多次点击而产生了副作用。举个最简单的例子,支付操作,用户购买商品后支付,支付扣款成功,但是返回结果的时候网络异常,此时钱已经扣了,用户再次点击按钮,此时会进行第二次扣款,返回结果成功,用户查询余额返发现多扣钱了,流水记录也变成了两条,这就是没能保证接口的幂等性

泠青沼 1030

基于STM32L4XX、HAL库的YT8531C-CA以太网收发器(PHY)驱动程序设计

是一款由裕太微推出的高性价比、低功耗的单端口 10/100M 以太网物理层收发器(PHY)。它通过标准的 MII(介质独立接口)或 RMII(精简介质独立接口)与微控制器的 MAC 层连接,实现将数字信号与网络模拟信号之间的转换。支持自动协商(Auto-Negotiation),自动选择最高速率和双工模式。支持 HP Auto-MDIX(自动交叉直连),无需区分直通线或交叉线。低功耗设计,特别适合电池供电或对功耗敏感的 STM32L4 应用。支持 MII 和 RMII 接口,节省引脚(RMII模式)。

zhusl6688的博客 626

什么是接口的幂等性,如何实现接口幂等性?一文搞定

同一个接口,多次发出同一个请求,必须保证操作只执行一次。

Java鱼仔的博客 2万+

基于 Qt C++ 的智能工厂数字孪生系统

你想要实现一个基于 Qt C++ 的智能工厂数字孪生系统,核心是 **Qt 3D** 场景搭建 + **实时数据驱动** 设备模型。下面我将为你提供一个完整的解决方案,包含 **核心思路、实现步骤、完整代码示例** 和 **注意事项**。| **渲染层** | 3D 场景搭建、设备模型加载、实时动画渲染、用户交互。| **业务逻辑层** | 数据处理(滤波、转换)、设备状态管理、动画逻辑控制。| **数据层** | 实时采集设备数据(如传感器、PLC、MES 系统),提供数据接口。

寒寒豆豆软件公司的博客 193

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

Spring-Boot-+-Redis-实现接口幂等性,看这篇就太好了!

幂等性的概念是,任意多次执行所产生的影响都与一次执行产生的影响相同,按照这个含义,最终的解释是对数据库的影响只能是一次性的,不能重复处理。手段如下数据库建立唯一索引token机制悲观锁或者是乐观锁先查询后判断小小主要带你们介绍Redis实现自动幂等性。其原理如下图所示。自定义一个注解,定义此注解的目的是把它添加到需要实现幂等的方法上,只要某个方法注解了其,都会自动实现幂等操作。其代码如下。

2401_83329718的博客 776

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

jmeter校验结果_【分享吧】接口幂等性校验的实现

概念幂等性, 通俗的说就是一个接口, 多次发起同一个请求, 必须保证操作只能执行一次,比如:●订单接口, 不能多次创建订单●支付接口, 重复支付同一笔订单只能扣一次钱●支付宝回调接口, 可能会多次回调, 必须处理重复回调●普通表单提交接口, 因为网络超时等原因多次点击提交, 只能成功一次等等常见解决方案●唯一索引 -- 防止新增脏数据●token机制 -- 防止页面重复提交●悲观锁 --...

weixin_39837727的博客 353

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

Springboot + redis + 注解 + 拦截器来实现接口幂等性校验

推荐:面试被问:高并发下的接口幂等性一、概念幂等性, 通俗的说就是一个接口, 多次发起同一个请求, 必须保证操作只能执行一次比如:订单接口, 不能多次创建订单支付接口, 重复支付同一笔订...

田维常 203

乐观锁实现接口幂等性_什么是接口的幂等性,如何实现接口幂等性?

什么是接口的幂等性,如何实现接口幂等性?(一)幂等性概念幂等性原本是数学上的概念,用在接口上就可以理解为:同一个接口,多次发出同一个请求,必须保证操作只执行一次。 调用接口发生异常并且重复尝试时,总是会造成系统所无法承受的损失,所以必须阻止这种现象的发生。 比如下面这些情况,如果没有实现接口幂等性会有很严重的后果: 支付接口,重复支付会导致多次扣钱 订单接口,同一个订单可能会多次创建。(二)幂等性...

weixin_35721505的博客 156

Spring Boot项目中使用Redis实现接口幂等性的方案

在开发Web应用时,接口幂等性是一项重要的设计原则,特别是在微服务架构中,确保一个操作多次执行仍能保持数据的一致性非常关键。幂等性指的是无论一个操作被执行多少次,结果都保持不变。Spring Boot项目中结合Redis实现接口幂等性是一种有效的策略,这种方法不仅能提高应用的稳定性,还能在分布式系统中保持数据一致性。

yinweilove999的博客 372

幂等校验是什么意思_什么是接口的幂等性,如何实现接口幂等性?一文搞定

每天一个知识点什么是接口的幂等性,如何实现接口幂等性?(一)幂等性概念幂等性原本是数学上的概念,用在接口上就可以理解为:同一个接口,多次发出同一个请求,必须保证操作只执行一次。调用接口发生异常并且重复尝试时,总是会造成系统所无法承受的损失,所以必须阻止这种现象的发生。比如下面这些情况,如果没有实现接口幂等性会有很严重的后果:支付接口,重复支付会导致多次扣钱 订单接口,同一个订单可能会多次...

weixin_39699912的博客 1838

Sprinig Boot优雅实现接口幂等性

一、概念幂等性, 通俗的说就是一个接口, 多次发起同一个请求, 必须保证操作只能执行一次比如:订单接口, 不能多次创建订单支付接口, 重复支付同一笔订单只能扣一次钱支付宝回调接口, 可能会多次回调, 必须处理重复回调普通表单提交接口, 因为网络超时等原因多次点击提交, 只能成功一次等等二、常见解决方案唯一索引 -- 防止新增脏数据token机制 -- 防止页面重复提交悲观锁 -- 获取数据的时候加锁(锁表或锁行)乐观锁 -- 基于版本号version实现, 在更新数据那一刻校验数据分布式锁 -- redis

z_ssyy的博客 491

Sprinig Boot实现接口幂等性,看完居然发现这么简单,纯干货!

一、概念 幂等性, 通俗的说就是一个接口, 多次发起同一个请求, 必须保证操作只能执行一次 比如: 订单接口, 不能多次创建订单 支付接口, 重复支付同一笔订单只能扣一次钱 支付宝回调接口, 可能会多次回调, 必须处理重复回调 普通表单提交接口, 因为网络超时等原因多次点击提交, 只能成功一次 等等 二、常见解决方案 唯一索引 -- 防止新增脏数据 token机制 -- 防止页...

Java0258的博客 323

自定义检验注解_神操作自定义Annotation实现通用的接口自动幂等

点击上方☝SpringForAll社区轻松关注!及时获取有趣有料的技术文章本文来源:http://rrd.me/g39x7前言: 在实际的开发项目中,一个对外暴露的接口往往会面临很多次请求,我们来解释一下幂等的概念:任意多次执行所产生的影响均与一次执行的影响相同。按照这个含义,最终的含义就是 对数据库的影响只能是一次性的,不能重复处理。如何保证其幂等性,通常有以下手段:1:数据库建立唯...

weixin_39928102的博客 102

分布式系统的“稳定密码”——幂等性,你知道多少?

幂等性是分布式系统设计中的关键概念,确保操作的幂等性可以提高系统的可靠性和一致性。通过结合业务需求,选择合适的幂等性方案,可以有效防止重复操作带来的问题,提升用户体验和系统稳定性。:如果幂等性键不存在,则在Redis中设置该键,值为IN_PROGRESS,并设置过期时间为10分钟,防止长期占用内存。利用缓存(如 Redis)存储已处理的请求标识,在处理请求前,先查询缓存,判断请求是否已处理。通过上述实现,确保了在高并发场景下,订单创建接口的幂等性,防止重复提交导致的数据不一致问题。如果失败,删除该键。

小健学Java的博客 1234

SpringBoot学习之使用拦截器和Redis实现接口幂等性

接口幂等性 什么是接口幂等性:接口幂等性就是用户对于同一操作发起的一次请求或者多次请求的结果是一致的,不会因为多次点击而产生了副作用。例如:用户购买商品后支付,支付扣款成功,但是返回结果的时候网络异常,此时钱已经扣了,用户再次点击按钮,此时会进行第二次扣款,返回结果成功,用户查询余额返发现多扣钱了,流水记录也变成了两条,这就是没有保证接口的幂等性。 导入依赖 <dependencies> <dependency> <groupId>

hxxx1314的博客 226
上一篇: spring boot 快速开发框架(集成mybatis-plus和增强swagger)
下一篇: List的去重, Java8 中distinct的使用
意田天
博客等级 码龄7年 41粉丝 89原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

意田天

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值