使用状态机实现幂等性

news/2024/4/20 18:50:50/文章来源:https://blog.csdn.net/asd1358355022/article/details/130326625

文章目录

  • 背景
  • 幂等概念
  • 适用场景
  • 示例代码
  • 上述代码状态流转

背景

        在某些场景下,可以使用状态机来实现幂等性。将业务流程抽象为一个状态机,定义各个状态之间的转换规则。当收到一个请求时,根据当前状态和请求类型来判断是否允许执行操作,如果允许则执行操作并更新状态,否则拒绝操作。这样可以确保每个操作在合适的状态下执行,避免重复操作导致的问题。

幂等概念

        幂等(Idempotency)是指对于一个系统,一个具有幂等性质的操作,无论执行多少次,其结果始终保持一致。在分布式系统和网络编程中,幂等性是一种非常重要的概念。确保接口幂等性可以避免重复操作导致的数据不一致和其他潜在问题。

        在计算机科学中,幂等性通常用于描述一种能够忽略重复调用的操作。例如,对于一个删除记录的操作,如果删除成功,无论执行多少次,记录都会保持被删除的状态。类似地,对于一个更新操作,如果更新成功,无论执行多少次,更新后的状态都保持不变。

适用场景

  1. 确定状态:根据业务场景,确定系统需要的状态。例如,在订单处理中,可能需要如下状态:待支付、已支付、已发货、已收货、已取消等。
  2. 定义状态转换规则:针对每个状态,定义允许的操作以及操作后的新状态。例如,在待支付状态下,允许操作是支付,支付成功后状态转为已支付。
  3. 操作条件判断:在执行操作之前,根据当前状态和请求类型判断是否允许执行操作。如果允许,则执行操作并更新状态;否则拒绝操作。
  4. 存储状态:将状态持久化存储,例如存储在数据库中。这样,在处理请求时,可以获取当前状态,并根据状态执行相应的操作。
  5. 幂等性处理:当接收到重复的请求时,可以根据当前状态判断请求是否有效。如果当前状态不允许执行请求的操作,则直接返回之前的响应结果,实现幂等性。

示例代码

        在这个示例中,创建了一个基于有限状态机的订单处理系统。我们首先定义了状态和操作的枚举类型,然后定义了一个状态转换接口。接着,我们创建了一个表示订单的类,并在主方法中初始化一个待支付的订单。

        接下来,我们创建了一个状态机映射,用于存储状态转换规则。对于每个状态和操作,我们定义了一个状态转换接口的实现。在执行操作时,我们根据订单的当前状态和请求的操作来查找相应的状态转换。如果找到了合适的状态转换,就执行转换并更新订单状态。如果没有找到合适的状态转换,说明操作无效。

import java.util.HashMap;
import java.util.Map;public class StateMachineExample {// 定义状态枚举public enum State {PENDING_PAYMENT,PAID,CANCELED}// 定义操作枚举public enum Operation {PAY,CANCEL}// 定义状态转换接口public interface StateTransition {State execute();}// 定义订单类public static class Order {private State state;public Order(State state) {this.state = state;}public State getState() {return state;}public void setState(State state) {this.state = state;}}public static void main(String[] args) {// 创建一个待支付的订单Order order = new Order(State.PENDING_PAYMENT);// 创建状态机映射Map<State, Map<Operation, StateTransition>> stateMachine = new HashMap<>();// *************定义状态转换规则*************//stateMachine.put(State.PENDING_PAYMENT, new HashMap<>());//待支付状态下业务规则stateMachine.get(State.PENDING_PAYMENT).put(Operation.PAY, () -> {System.out.println("支付成功");return State.PAID;});stateMachine.get(State.PENDING_PAYMENT).put(Operation.CANCEL, () -> {System.out.println("订单已取消");return State.CANCELED;});//支付状态下业务规则stateMachine.put(State.PAID, new HashMap<>());stateMachine.get(State.PAID).put(Operation.PAY, () -> {System.out.println("重复支付,忽略");return State.PAID;});//订单取消状态下业务规则stateMachine.put(State.CANCELED, new HashMap<>());stateMachine.get(State.CANCELED).put(Operation.PAY, () -> {System.out.println("订单已取消,无法支付");return State.CANCELED;});// *****************************************//// 执行操作executeOperation(order, stateMachine, Operation.PAY);executeOperation(order, stateMachine, Operation.PAY);executeOperation(order, stateMachine, Operation.CANCEL);}// 根据当前状态和操作执行状态转换private static void executeOperation(Order order, Map<State, Map<Operation, StateTransition>> stateMachine, Operation operation) {State currentState = order.getState();StateTransition transition = stateMachine.get(currentState).get(operation);if (transition != null) {State newState = transition.execute();order.setState(newState);} else {System.out.println("操作无效");}}
}

执行结果
在这里插入图片描述

上述代码状态流转

  1. 当订单处于 PENDING_PAYMENT(待支付)状态时,执行 PAY 操作会将订单状态变为 PAID(已支付);执行 CANCEL 操作会将订单状态变为 CANCELED(已取消)。
  2. 当订单处于 PAID(已支付)状态时,再次执行 PAY 操作会被忽略,订单状态保持为 PAID
  3. 当订单处于 CANCELED(已取消)状态时,不存在定义的状态转换。

这样就保证在多次操作的时候只有一个结果,就保证了幂等性
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_102247.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数学知识四

容斥原理 S表示面积&#xff0c;下面公式可求出不相交的面积 2个圆的公式是这样 4个圆的面积是 总面积-所有俩俩相交的面积所有三三相交的面积-四四相交的面积&#xff0c;公式里加和减互相出现。 从n个集合里面挑一个一直到从n个集合里面挑n个 1-10中&#xff0c;能被2&#x…

【 SpringBoot单元测试 和 Mybatis 增,删,改 操作 】

文章目录 一、Spring-Boot单元测试(了解)1.1 概念1.2 单元测试引用1.3 单元测试的实现1.4 简单的断言说明1.5 单元测试优点 二、Mybatis 增&#xff0c;删&#xff0c;改 操作2.1 增加⽤户操作2.2 修改⽤户操作2.3 删除⽤户操作 一、Spring-Boot单元测试(了解) 1.1 概念 单元测…

645. 错误的集合|||697. 数组的度|||448. 找到所有数组中消失的数字

645. 错误的集合 题目 集合 s 包含从 1 到 n 的整数。不幸的是&#xff0c;因为数据错误&#xff0c;导致集合里面某一个数字复制了成了集合里面的另外一个数字的值&#xff0c;导致集合 丢失了一个数字 并且 有一个数字重复 。 给定一个数组 nums 代表了集合 S 发生错误后的…

教你轻松申请Azure OpenAI

Azure OpenAI 和 OpenAI 官方提供的服务基本是一致的&#xff0c;但是目前前者还是处于预览版的状态&#xff0c;一些功能还没有完全开放。 优点&#xff1a; 不受地域限制&#xff0c;国内可以直接调用。可以自己上传训练数据进行训练&#xff08;据说很贵&#xff09;。Azu…

Cloud Kernel SIG月度动态:发布 Anolis 8.8 镜像、kABI 社区共建流程

Cloud Kernel SIG&#xff08;Special Interest Group&#xff09;&#xff1a;支撑龙蜥内核版本的研发、发布和服务&#xff0c;提供生产可用的高性价比内核产品。 01 SIG 整体进展 Anolis 8.8 镜像发布&#xff0c;默认搭载 ANCK 5.10-013 版本。 Anolis 23 滚动内核更新至…

Windows下版本控制器(SVN)-验证是否安装成功+配置版本库+启动服务器端程序

文章目录 基础知识-Windows下版本控制器(SVN)3、Subversion 安装与配置3.1 验证是否安装成功。3.2 配置版本库3.3 启动服务器端程序 基础知识-Windows下版本控制器(SVN) 3、Subversion 安装与配置 TortoiseSVN安装与配置网上资料太多了&#xff0c;这里就不阐述了。 3.1 验证是…

【Java代码】MP3、flac歌曲批量生成同名的“xxx.lrc”歌词文件导入索尼黑砖二代

目录 1、准备条件2、实现方式3、代码环境和maven依赖4、Java代码5、示例1结果6、示例2结果7、一个小问题8、“音乐标签”下载地址 1、准备条件 网易云下载的MP3、flac后缀的歌曲若干首&#xff08;ncm后缀的歌曲需要还原格式&#xff0c;不然会随着VIP过期而无法听&#xff09…

【原理图专题】案例:从集成的电平转换芯片换成三极管分立电平转换怎么就报异常

本案例是一个已经小批量量产的设备,不是我测试出来的,但是也算是我之前一手造成的,因为原理图这部分是我修改的。 异常发现最近生产的整机有部分非接读卡时无法控制到蜂鸣器发声音。我们的设计是这样的,有两个MCU互相通信,一个MCU是控制蜂鸣器的,另一个MCU通过SPI与非接芯…

银行数字化转型导师坚鹏:银行业务数字化创新工作坊

银行业务数字化创新工作坊 课程背景&#xff1a; 很多银行存在以下问题&#xff1a; 不清楚如何进行业务数字化创新&#xff1f; 不知道如何开展银行数字化营销工作&#xff1f; 不知道零售业务数字化创新成功案例&#xff1f; 学员收获&#xff1a; 学习原创银行BLM…

docker容器内的应用利用k8s configmap做配置中心

ConfigMap 能带来什么好处&#xff1f; 传统的应用服务都有自己的配置文件&#xff0c;各自配置文件存储在服务所在节点。如果配置出现变更&#xff0c;就需要对应节点的配置文件。Kubernetes 利用了 Volume 功能&#xff0c;完整设计了一套配置中心&#xff0c;其核心对象就是…

阳光万里,祝你上岸——免统考在职研究生

什么是在职研究生 在职研究生&#xff0c;是国家计划内&#xff0c;以在职人员身份&#xff0c;部分时间在职工作&#xff0c;部分时间在校学习的研究生教育的一种类型。在职攻读硕士方式有三种&#xff1a; 1.双证非全日制研究生&#xff1a;为普通高等教育研究生学历&#x…

Android OpenGL 渲染相机预览画面显示体系

OpenGL能进行高效得渲染图形图像&#xff0c;并支持各种复杂的特效和动画。 而在 Android 当中&#xff0c;运用的是OpenGL ES&#xff0c;它是OpenGL的一个轻量级版本&#xff0c;专门用于在移动设备、游戏控制台、嵌入式系统等嵌入式环境中使用。 它可以做相机滤镜或者图片…

seata1.6.0 单机,集群搭建 基于nacos注册中心 mysql数据库

seata1.6.0 单机&#xff0c;集群搭建 基于nacos注册中心 mysql数据库 大纲 1 单机搭建2 集群搭建 由于项目中的dubbo版本为2.6.0 故客户端程序&#xff08;TM RM&#xff09;使用seata-all 1.4.2 &#xff0c;服务端&#xff08;TC&#xff09;使用seata-server-1.6.0.zip …

MIT6.S081操作系统实验2021(xv6系统)——lab1 Xv6 and Unix utilities

MIT6.S081操作系统实验2021——lab1 参考文章 sleep 要求为xv6实现UNIX 程序sleep&#xff1b;其应该暂停用户指定的ticks number。tick是 xv6 内核定义的时间概念&#xff0c;即计时器芯片的两次中断之间的时间&#xff08;两次时钟中断之间的时间&#xff09;。您的解决方…

关于函数栈帧的创建与销毁和可变参数列表

目录 1. 深刻理解函数调用过程1.1 基本概念1.2 函数栈帧的创建于销毁1.2.1 栈帧创建1.2.2 栈帧销毁1.2.3 有趣的现象 2. 了解可变参数列表的使用与原理2.1 可变参数列表与函数栈帧的关系2.2 宏的工作过程2.3 宏的具体实现原理 1. 深刻理解函数调用过程 1.1 基本概念 关于函数…

【MySQL】(7)复合查询

文章目录 单表查询回顾与练习多表查询自连接多行子查询&#xff08;单列&#xff09;in 运算符all 关键字any 关键字 多列子查询from 子句中的子查询合并查询 单表查询回顾与练习 注&#xff1a;下面的依旧基于 scott 数据库 MariaDB [scott]> select * from emp; -------…

ASEMI代理ADG736BRMZ-REEL7原装ADI车规级ADG736BRMZ-REEL7

编辑&#xff1a;ll ASEMI代理ADG736BRMZ-REEL7原装ADI车规级ADG736BRMZ-REEL7 型号&#xff1a;ADG736BRMZ-REEL7 品牌&#xff1a;ADI /亚德诺 封装&#xff1a;MSOP-10 批号&#xff1a;2023 安装类型&#xff1a;表面贴装型 引脚数量&#xff1a;10 类型&#xff1…

Mybatis框架超详解及运用总结

Mybatis 一、什么是Mybatils&#xff1f;二、第一个Mybatils程序2.1、创建springboot工程2.2、准备数据2.3、配置MyBatis2.4、编写SQL语句2.5、单元测试 三、JDBC四、数据库连接池五、lombok六、Mybatis基础操作6.1、删除6.2、新增6.2.1、主键返回 6.3、修改6.4、查询6.4.1、数…

推式配货(Push)、拉式配货(Pull)和配送需求计划(DRP)的区别

随着电子商务的迅猛发展&#xff0c;物流配送服务已然成为企业竞争最为核心的环节&#xff0c;一个全面、完善的物流配送方案&#xff0c;能够帮助企业满足客户交期、节约运输和库存成本&#xff0c;促进各环节沟通&#xff0c;提高生产稳定性。同时&#xff0c;物流配送的许多…

垃圾回收概述

什么是垃圾 垃圾收集&#xff0c;不是Java语言的伴生产物。早在1960年&#xff0c;第一门开始使用内存动态分配和垃圾收集技术的Lisp语言诞生。 关于垃圾收集有三个经典问题&#xff1a; 哪些内存需要回收&#xff1f;什么时候回收&#xff1f;如何回收&#xff1f; 垃圾收…