高并发下如何保证接口的幂等性?

本人花费半年的时间总结的《Java面试指南》已拿腾讯等大厂offer,已开源在github ,欢迎star!

转载声明:转载请注明出处,本技术博客是本人原创文章

本文GitHub https://github.com/OUYANGSIHAI/JavaInterview 已收录,这是我花了6个月总结的一线大厂Java面试总结,本人已拿大厂offer,欢迎star

原文链接:blog.ouyangsihai.cn >> 高并发下如何保证接口的幂等性?

介绍

幂等性就是同一个操作执行多次,产生的效果一样。如http的get请求,数据库的select请求就是幂等的

在分布式系统中,保证接口的幂等性非常重要,如提交订单,扣款等接口都要保证幂等性,不然会造成重复创建订单,重复扣款,那么如何保证接口的幂等性呢?

前端保证幂等性的方法

按钮只能点击一次

用户点击按钮后将按钮置灰,或者显示loading状态

RPG模式

即Post-Redirect-Get,当客户提交表单后,去执行一个客户端的重定向,转到提交成功页面。避免用户按F5刷新导致的重复提交,也能消除按浏览器后退键导致的重复提交问题。目前绝大多数公司都是这样做的,比如淘宝,京东等

后端保证幂等性的方法

使用唯一索引

对业务唯一的字段加上唯一索引,这样当数据重复时,插入数据库会抛异常

状态机幂等

如果业务上需要修改订单状态,例如订单状态有待支付,支付中,支付成功,支付失败。设计时最好只支持状态的单向改变。这样在更新的时候就可以加上条件,多次调用也只会执行一次。例如想把订单状态更新为支持成功,则之前的状态必须为支付中


update table_name set status = 支付成功 where status = 支付中

乐观锁实现幂等

  1. 查询数据获得版本号1. 通过版本号去更新,版本号匹配则更新,版本号不匹配则不更新
    ```

– 假如查询出的version为1
select version from table_name where userid = 10;
– 给用户的账户加10
update table_name set money = money -10, version = version + 1 where userid = 10 and version = 1



也可以通过条件来实现乐观锁,如库存不能超卖,数量不能小于0

update table_name set num = num - 10 where num - 10 >= 0

```

防重表

增加一个防重表,业务唯一的id作为唯一索引,如订单号,当想针对订单做一系列操作时,可以向防重表中插入一条记录,插入成功,执行后续操作,插入失败,则不执行后续操作。本质上可以看成是基于MySQL实现的分布式锁。根据业务场景决定执行成功后,是否删除防重表中对应的数据

分布式锁实现幂等

执行方法时,先根据业务唯一的id获取分布式锁,获取成功,则执行,失败则不执行。分布式锁可以基于redis,zookeeper,mysql来实现,分布式锁的细节就不介绍了

select+insert

先查询一下有没有符合要求的数据,如果没有再执行插入。没有并发的系统中可以保证幂等性,高并发下不要用这种方法,也会造成数据的重复插入。我一般做消息幂等的时候就是先select,有数据直接返回,没有数据加分布式锁进行insert操作

全局唯一号实现幂等

通过source(来源)+ seq(序列号)来判断请求是否重复,重复则直接返回请求重复提交,否则执行。如当多个三方系统调用服务的时候,就可以采用这种方式

最后,再附上我历时三个月总结的 Java 面试 + Java 后端技术学习指南,笔者这几年及春招的总结,github 1.4k star,拿去不谢!

下载方式

1. 首先扫描下方二维码

2. 后台回复「Java面试」即可获取

原文地址:https://sihai.blog.csdn.net/article/details/109465778

本人花费半年的时间总结的《Java面试指南》已拿腾讯等大厂offer,已开源在github ,欢迎star!

转载声明:转载请注明出处,本技术博客是本人原创文章

本文GitHub https://github.com/OUYANGSIHAI/JavaInterview 已收录,这是我花了6个月总结的一线大厂Java面试总结,本人已拿大厂offer,欢迎star

原文链接:blog.ouyangsihai.cn >> 高并发下如何保证接口的幂等性?


 上一篇
一些恶心的代码片段,你看了就知道! 一些恶心的代码片段,你看了就知道!
点击上方 **好好学java **,选择 **星标 **公众号 重磅资讯、干货,第一时间送达 今日推荐:2020年7月程序员工资统计,平均14357元,又跌了,扎心个人原创100W+访问量博客:点击前往,查看更多 1、下面一段代码将
2021-04-04
下一篇 
Mybatis一级缓存,二级缓存的实现就是这么简单 Mybatis一级缓存,二级缓存的实现就是这么简单
介绍又到了一年面试季,所以打算写一点面试常问的东西,争取说的通俗易懂。面试高级岗,如果你说熟悉Mybatis,下面这些问题基本上都会问 如何写一个分页插件?1. 1. Mybatis的一级缓存和二级缓存的工作原理,会遇到什么问题?1
2021-04-04