首页 > 编程语言 >程序接口幂等性设计

程序接口幂等性设计

时间:2024-12-09 18:54:56浏览次数:3  
标签:请求 程序接口 redis update token 设计 id 分布式

程序接口幂等性设计

接口幂等性是指用户对于同一操作发起的一次请求或者多次请求的结果是一致的,不会因为多次点击而产生了副作用。
这类问题多发于接口的:
insert操作,这种情况下多次请求,可能会产生重复数据。
update操作,如果只是单纯的更新数据,比如:update user set status=1 where id=1,是没有问题的。如果还有计算,比如:update user set status=status+1 where id=1,这种情况下多次请求,可能会导致数据错误。

1. insert前先select

2. 加悲观锁
update user amount = amount-100 where id=123;
select * from user id=123 for update;
需要特别注意的是:如果使用的是mysql数据库,存储引擎必须用innodb,因为它才支持事务。此外,这里id字段一定要是主键或者唯一索引,不然会锁住整张表。

3. 加乐观锁
既然悲观锁有性能问题,为了提升接口性能,我们可以使用乐观锁。需要在表中增加一个timestamp或者version字段,这里以version字段为例。
select id,amount,version from user id=123;
update user set amount=amount+100,version=version+1 where id=123 and version=1;

4. 加唯一索引
alter table `order` add UNIQUE KEY `un_code` (`code`);
加了唯一索引之后,第一次请求数据可以插入成功。但后面的相同请求,插入数据时会报Duplicate entry '002' for key 'order.un_code异常,表示唯一索引有冲突。
如果是java程序需要捕获:DuplicateKeyException异常,如果使用了spring框架还需要捕获:MySQLIntegrityConstraintViolationException异常。

5. 建防重表
有时候表中并非所有的场景都不允许产生重复的数据,只有某些特定场景才不允许。这时候,直接在表中加唯一索引,显然是不太合适的。
该表可以只包含两个字段:id 和 唯一索引,唯一索引可以是多个字段比如:name、code等组合起来的唯一标识,例如:susan_0001。

6. 根据状态机
update `order` set status=3 where id=123 and status=2;
主要特别注意的是,该方案仅限于要更新的表有状态字段,并且刚好要更新状态字段的这种特殊情况,并非所有场景都适用。

7. 加分布式锁
其实前面介绍过的加唯一索引或者加防重表,本质是使用了数据库的分布式锁,也属于分布式锁的一种。但由于数据库分布式锁的性能不太好,我们可以改用:redis或zookeeper。
鉴于现在很多公司分布式配置中心改用apollo或nacos,已经很少用zookeeper了,我们以redis为例介绍分布式锁。
目前主要有三种方式实现redis的分布式锁:
setNx命令
set命令
Redission框架
具体步骤:
用户通过浏览器发起请求,服务端会收集数据,并且生成订单号code作为唯一业务字段。
使用redis的set命令,将该订单code设置到redis中,同时设置超时时间。
判断是否设置成功,如果设置成功,说明是第一次请求,则进行数据操作。
如果设置失败,说明是重复请求,则直接返回成功。
需要特别注意的是:分布式锁一定要设置一个合理的过期时间,如果设置过短,无法有效的防止重复请求。如果设置过长,可能会浪费redis的存储空间,需要根据实际业务情况而定。

8. 获取token
第一次请求获取token
第二次请求带着这个token,完成业务操作。

服务端生成token,保存到redis中,然后返回给浏览器。
用户通过浏览器发起请求时,携带该token。
在redis中查询该token是否存在,如果不存在,说明是第一次请求,做则后续的数据操作。
如果存在,说明是重复请求,则直接返回成功。
在redis中token会在过期时间之后,被自动删除。
需要特别注意的是:token必须是全局唯一的。

标签:请求,程序接口,redis,update,token,设计,id,分布式
From: https://www.cnblogs.com/oktokeep/p/18595820

相关文章

  • Chromium源码分析三:Chromium中用到的设计模式
    在阅读Chromium源码过程中,主要看的是公司自研的部分,不能对外分享。在自研部分中,用到了很多设计模式。比如:js注册监听函数,底层发现登录状态发生变化,产生登录或退登事件,事件从底层传到js层,就主要用到了观察者模式、代理模式、桥接模式、命令模式等。下面内容是通过询问AI生成的文......
  • 基于SSM框架的校园订餐小程序设计与实现
    内容概要:该文章介绍了使用SSM(Spring+SpringMVC+MyBatis)框架及Java开发语言和MySQL数据库,设计并实现了一款名为“校园订餐”的小程序。文中从系统需求出发,阐述了系统背景意义与国内外研究现状发展趋势,明确了需求并分析了系统可行性。随后详细讲解了系统的功能模块、数据库......
  • StarRocks 的架构、数据存储及表设计
    1.架构1.1.整体架构StarRocks的架构相对简单。(1).整个系统只包含两种类型的组件,前端(FE)和后端(BE),StarRocks不依赖任何外部组件,简化了部署和维护。(2).FE和BE可以在不停机的情况下横向扩展。(3).StarRocks具有元数据和服务数据的复制机制,这增加了数据的可靠性,并有效地防......
  • C++_默认构造函数和重载以及设计模式
    类和类之间关系类外:静态变量,是在编译阶段就分配好空间,对象还没创建的时候就有了空间类:类-对象-对象是类的一个实例类头(classhead)和类体(classbody)。将数据和行为封装在单个单元中--封装成员变量成员函数成员变量称为属性(property);成员函数称为方法(metho......
  • springboot毕设垂钓分享交流网的设计与实现程序+论文
    系统程序文件列表开题报告内容研究背景随着互联网技术的飞速发展和人们生活水平的提高,垂钓作为一种休闲娱乐活动,越来越受到广大爱好者的青睐。然而,目前市场上关于垂钓的信息分享和交流平台相对较少,且功能单一,无法满足垂钓爱好者日益增长的需求。许多垂钓者渴望找到一个能够......
  • node.js毕设基于SpringoBoot的新能源汽车租赁换电管理系统的设计与实现 论文+程序
    本系统(程序+源码+数据库+调试部署+开发环境)带文档lw万字以上,文末可获取源码系统程序文件列表开题报告内容一、选题背景随着新能源汽车产业的蓬勃发展,新能源汽车租赁业务逐渐兴起。关于新能源汽车租赁管理的研究,现有研究主要以传统充电模式下的租赁管理为主,专门针对换电模......
  • 《 bilibili-起步级 接口文档设计 经验分享 ~ 》# 用户模块
    bilibili-用户模块接口设计-经验分享~#用户模块数据库er关系图:迅速跳转链接枚举码实体类:迅速跳转链接使用apifox.json格式导入接口文档步骤登录Apifox。新建文件,将代码粘贴到该文件,并更改后缀为.apifox.json进入项目,点击“导入”。选择“Apifox”格式......
  • Python商场停车计费系统设计与实现_urqs9
    文章目录项目介绍具体实现截图开发技术设计思路开发与测试:核心代码部分展示文章目录/协作提纲源码/演示视频获取方式项目介绍随着人们生活水平的高速发展,智能停车计费信息管理方面在近年来呈直线上升,人们也了解到智能停车计费的实用性,因此智能停车计费的管理也逐年......
  • python毕设的殡仪馆信息管理系统设计与实现ou64v程序+论文
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容研究背景殡仪馆作为社会公共服务体系的重要组成部分,承担着为逝者提供尊严告别、为家属提供慰藉的重要职责。然而,传统的殡仪馆管理方式存在诸多不足......
  • 大一学生《Web前端网课作业》基于HTML+CSS自我介绍网页设计与制作
    ......