java幂等控制_JAVA幂等性实现

article/2025/9/25 10:17:07

什么是幂等:

贴一张百度百科的图:

012a0642e27f3b254d0f747c885826f3.png

简单来说幂等保证了只要调用接口成功,外部多次调用对系统的影响是一致的,也就是一个请求多次重试的问题。

需要考虑幂等的场景:

客户端存在多次提交或者超时重试的情况;

分布式架构中因网络波动采用重试机制,如Dubbo的重试机制;

消息推送重试,如MQ重试;

不幂等带来的影响:比如在支付场景下,消费者消费扣款消息,对一笔订单进行扣款操作,该扣款操作需要扣除100元,在不幂等的情况下,如果消费者多次发起请求,就会造成多次扣款。

幂等性问题解决方案

幂等问题演示:

执行如下SQL,初始化金额为100;

create table order_pay

(

id int default 0 not null

primary key,

amt decimal(9, 2) default 0.00 null comment '金额',

status int null comment '状态:0已完成/1处理中'

)comment '订单支付表';

INSERT INTO test.order_pak (id, amt, status) VALUES (1, 100.00, 0);

复制代码

pay接口:

@RestController

@RequestMapping("/test/order-pay")

public class OrderPayController {

@Autowired

IOrderPayService orderPayService;

@ApiOperation(httpMethod = "POST", value = "幂等性测试")

@PostMapping("pay")

public Resp pay(@RequestBody Req req) {

PayReq payReq = req.getData();

OrderPay order = orderPayService.getOne(new LambdaQueryWrapper().eq(OrderPay::getId, payReq.getBizId()));

order.setAmt(order.getAmt().subtract(payReq.getAmt()));

orderPayService.updateById(order);

return Resp.success("剩余金额更新为"+order.getAmt());

}

}

复制代码

在不控制幂等的情况下,对pay接口连续发起5次请求,每一次扣减金额为10.00:

cf8e22c19042bb42dce07452c419500d.bmp

可以看到最后剩余金额更新为50 .00,我们发起一次请求,应该只扣除10.00,当遇到网络重复或系统bug在不控制幂等的情况下会导致系统进行了多次扣款。那如何进行幂等控制呢?有什么方法呢?

幂等性的实现

保证幂等性的措施包括但不限于:

1、表单提交后按钮置灰

限制客户端请求

2、添加唯一索引

把唯一标识作为唯一索引,在重复创建时会抛出唯一约束异常

3、全局唯一ID

针对业务操作和内容生产全局唯一ID,在执行操作时判断ID是否存在来判断是否已执行

4、一锁二查三更新

如果在流程处理过程中,业务要求不能并发执行,可以在流程执行之前根据业务ID获取锁,其他流程执行时获取锁就会失败,也就是同一时间该流程只能有一个能执行成功,执行完成后,释放锁,同时也需要在入口处增加业务状态的判断,以避免对请求的多次处理。这种方式不止可用于幂等的控制,也可以防止并发操作带来的异常。

@ApiOperation(httpMethod = "POST", value = "幂等性测试")

@PostMapping("pay")

public Resp pay(@RequestBody Req req) throws Exception {

PayReq payReq = req.getData();

// 获取分布式锁

redisTools.lock(payReq.getBizId().toString());

OrderPay order = orderPayService.getOne(new LambdaQueryWrapper().eq(OrderPay::getId, payReq.getBizId()));

if (order.getStatus()==1){

order.setAmt(order.getAmt().subtract(payReq.getAmt()));

order.setStatus(0);

orderPayService.updateById(order);

}

// 释防锁

redisTools.unlock(payReq.getBizId().toString());

return Resp.success("剩余金额为"+order.getAmt());

}

复制代码

以下是对pay接口进行并发请求5次的结果:

38298d5c7e2048c159f6b445f05fd2ba.png

可以看到,只有1个请求可以请求成功,另外4个请求在 redisTools.lock(payReq.getBizId().toString())获取分布式锁的步骤中抛出异常。

不加锁与加锁的区别

如果把分布式锁的步骤去掉会发生什么样的情况呢?

@ApiOperation(httpMethod = "POST", value = "幂等性测试")

@PostMapping("pay")

public Resp pay(@RequestBody Req req) throws Exception {

PayReq payReq = req.getData();

OrderPay order = orderPayService.getOne(new LambdaQueryWrapper().eq(OrderPay::getId, payReq.getBizId()));

if (order.getStatus()==1){

order.setAmt(order.getAmt().subtract(payReq.getAmt()));

order.setStatus(0);

orderPayService.updateById(order);

}

return Resp.success("剩余金额为"+order.getAmt());

}

复制代码

依旧对pay接口进行并发请求5次,查看日志:

34779ea819e024de62a2adc08c891e86.png

5次请求都成功了,但是逻辑执行了5遍,在复杂的业务流程下可能会引发其他不必要问题。

总结:

在系统设计中,实现幂等的方案有很多种,要根据自身系统的特性优先选择小而巧方案,避免形成过于复杂的方案。


http://chatgpt.dhexx.cn/article/lOeOfpEf.shtml

相关文章

幂等问题

点击↑上方↑蓝色“编了个程”关注我~ 每周至少一篇原创文章 这是本公众号的第 34 篇原创文章 最近比较懒,好几周没写文章了。还是没能坚持每周更新,愧对关注我的读者和自己的flag。。。 不过还好调整了过来,还是会继续坚持周更的。毕竟学习是…

常见的幂等性解决方案

背景 我们实际系统中有很多操作,是不管做多少次,都应该产生一样的效果或返回一样的结果。 get请求一般没有幂等性需求、delete请求一般也没有幂等性需求,post、update视情况而定例如: 前端重复提交选中的数据,应该后…

彻底理解接口幂等性

目录 背景 1. 幂等性的概念 2.什么情况需要处理接口幂等性问题? 2.1 select 天然自带幂等性。 2.2 insert 当我们重复插入数据的时候,会出现什么情况 ? 2.3 delete 是否具有幂等性? 2.4 update 猜一猜是否具有天热幂等性&a…

【实战】聊聊幂等设计

前言 大家好,今天我们一起来聊聊幂等设计。 什么是幂等为什么需要幂等接口超时,如何处理呢?如何设计幂等?实现幂等的8种方案HTTP的幂等1. 什么是幂等? 幂等是一个数学与计算机科学概念。 在数学中,幂等用函数表达式就是:f(x) = f(f(x))。比如求绝对值的函数,就是幂等…

幂等性 详解

目录 一、幂等概念 1、幂等的数学概念 2. 幂等的业务概念 二、幂等概述 三、幂等场景 四、解决方案 1、token redis机制 2、乐观锁机制 3、唯一主键机制 4、去重表机制 5、门票机制 一、幂等概念 1、幂等的数学概念 如果在一元运算中,x 为某集合中的任…

幂等 (idempotence) 的概念

幂等 (idempotence) 的概念 幂等的数学概念 幂等是源于一种数学概念。其主要有两个定义 如果在一元运算中,x 为某集合中的任意数,如果满足 f(x) f(f(x)) ,那么该 f 运算具有幂等性,比如绝对值运算 abs(a) abs(abs(a)) 就是幂…

偏度

偏度公式如下: 现在想解决如何从图像上解决为正为负的问题,如图所示: 个人理解:偏度中的偏是针对变量相对于中心点(期望值)距离的一种描述;如果厚尾的话,就说明有很多点距离中心点比…

偏度(skewness)

偏度 偏度(skewness),是统计数据分布偏斜方向和程度的度量,是统计数据分布非对称程度的数字特征。定义上偏度是样本的三阶标准化矩。 偏度定义中包括正态分布(偏度0) 算术平均值 中位数 众数,…

策略梯度

Policy Gradient Methods for Reinforcement Learning with Function Approximation(PG) 在强化学习的算法中存在两种算法,一个是基于价值函数的算法,另一个是基于策略梯度的算法。为什么要提出策略梯度算法呢? 基于策略的学习可能会具有更好…

推荐系统中的偏差

推荐系统消偏 推荐系统中的偏差IPW ——逆概率加权DICE ——区分兴趣和偏差建模因果推断 推荐系统中的偏差 预估问题 我们一般会注重两种误差,偏差和方差, 方差与模型泛化能力有关:通常关注模型的复杂度与是否过拟合;偏差则表现为…

特征偏度和异常值处理

(一)机器学习基础 - 偏度、正态化以及 Box-Cox 变换 https://my.oschina.net/mathinside/blog/4942126 对于数据挖掘、机器学习中的很多算法,往往会假设变量服从正态分布。例如,在许多统计技术中,假定误差是正态分布…

推荐系统去偏(Debiased Recommendation)研究进展概述

©作者 | 张景森 学校 | 中国人民大学信息学院硕士 文章来源 | RUC AI Box 引言 推荐系统作为解决信息过载的一种重要手段,已经在不同的应用场景下取得了不错的效果。近些年来关于推荐系统的研究主要集中在如何设计更好的模型来适应用户行为数据,进而…

【综述】推荐系统偏差问题 去偏最新研究进展(Bias and Debias in Recommender System)

文章目录 1. 推荐系统的反馈回路1.1 User -> Data1.2 Data -> Model1.3 Model -> User 2. 推荐系统中的Bias2.1 数据偏差(data bias)2.1.1 选择偏差(Selection Bias)2.1.2 曝光偏差(Exposure Bias)2.1.3 一致性偏差(Conformity Bias)2.1.4 位置偏差(Position Bias) 2.…

数据偏度介绍和处理方法

偏度(skewness)是用来衡量概率分布或数据集中不对称程度的统计量。它描述了数据分布的尾部(tail)在平均值的哪一侧更重或更长。偏度可以帮助我们了解数据的偏斜性质,即数据相对于平均值的分布情况。 有时,正…

【期权系列】基于偏度指数的择时分析

【期权衍生指标系列】基于偏度指数的择时分析 本篇文章是基于研究报告的复现作品,旨在记录个人的学习过程和复现过程中的一些思路。 感谢中信期货研究员前辈的宝贵思路。 一、偏度指数 1.偏度指数简介 偏度是描述数据分布形态的统计量,其描述的是统…

对于偏度的理解

偏度公式如下: 现在想解决如何从图像上解决为正为负的问题,如图所示:? 个人理解:偏度中的偏是针对变量相对于中心点(期望值)距离的一种描述;如果厚尾的话,就说明有很多点…

量化策略研究:股票中的偏度效应

2022年4月份以来,加密货币市场的暴跌强调了市场中性策略的重要性;基于此,有部分Quanter提出了基于加密货币的偏度策略:“Skewness/Lottery Trading Strategy in Cryptocurrencies”。 为此,小编不禁好奇:偏…

Maven安装和配置(详细版)

Maven安装和配置 Maven安装1、安装链接:2、配置环境变量: Maven配置1、修改Maven仓库下载镜像及修改仓库位置:2、在Idea上配置Maven: 测试Maven安装能否安装jar包 Maven安装 1、安装链接: Maven – Download Apache …

Maven 安装/学习入门详解!

Maven安装: Maven 软件的下载 为了使用 Maven 管理工具,我们首先要到官网去下载它的安装软件。通过百度搜索“Maven 点击 Download 链接,就可以直接进入到 Maven 软件的下载页面: 我们当时使用的是 apache-maven-3.5.2 版本&a…

Maven安装(超详解)

2.4.1 下载 下载地址:Maven – Download Apache Maven 在提供的资料中,已经提供了下载好的安装包。如下 : 2.4.2 安装步骤 Maven安装配置步骤: 解压安装 配置仓库 配置Maven环境变量 1、解压 apache-maven-3.6.1-bin.zip&a…