基于订单号可重入的交易系统接口设计探讨

2023-05-16

基于订单号可重入的交易系统接口设计探讨

       在交易系统的设计和实现中,接口的可重入性设计是及其关键的,可重入性也叫接口操作的冥等性保障,那么什么叫冥等性呢?在交易系统中,为什么需要这个特性?

       冥等性,顾名思义,就是接口的多次操作和一次操作的效果是一样的,这里的效果指的是对后端系统的状态变更不存在副作用(side-effect)。举一个例子,比如查询类接口,都是具有冥等性的,对同一输入参数的多次查询操作,都没有对后端系统的状态变更产生副作用,或者说,后端系统的状态不会因为该查询接口的调用而发生变化。当然,我们这里所说的冥等性,不是指查询类接口,而是指写入类或者变更类接口,变更类接口一般都会对后端系统的状态进行变更操作(即写操作),那么,在交易系统中,为什么该特性及其重要?这是因为交易系统一般都是资金敏感型系统,每次的系统状态的变更对应了资金或者订单状态等关键业务变量的变更。若服务调用方调用服务方由于网络等原因导致前一次接口调用返回不明确的时候,此时服务调用方是无法确认此处的交易是否已经成功提交的。举个例子,该交易接口是一次往某个朋友转账1000元的接口,每调一次转账1000元,这个时候,调用方单独通过该接口返回(超时了,返回的是系统繁忙类似的信息)无法判断本次是否已经成功转账,那么这个时候,调用方可以怎么做呢?方法可能有三种:1,调用一下查询接口,查一下该笔转账订单的状态是否已经成功;2,继续用同样的参数调用一次该接口,这叫重试;3,等着隔天对账的时候,再确认改笔转账是否成功。而其中第2种方法存在较大的风险,假如前面那次转账其实是已经成功了,只是接口返回包的时候网络超时,使得接口调用方无法获知本次接口调用的成功结果,如果这个时候,接口调用方再次调用一次,服务提供方的接口如果没有做好冥等性的保障,则会出现第二次调用也成功,相当于转账了两笔,即重复支付导致的资金安全问题。

        读者可能会问,既然这样,那接口调用方,只用方法1和3就可以了,不重试调用就是了,理论上好像也可以,但仔细琢磨还是有问题的:1,查询接口缺少事务型的保障,其实还是有一定的风险的,即单独依靠查询接口无法彻底解决这个问题,举个例子就明白了:还是上面的转账例子,调用方第一次调用转账接口返回网络超时,此时,考虑到该接口可能不具备冥等性,那么就不敢直接重试,先调用一次查询接口,查询一下状态,如果此时若订单已经支付成功则更新本地订单状态为转账成功后流程结束,若此时查询的是订单状态还是初始状态(即未转账成功),则再调用该转账接口重试一次,问题是这样调用是安全的么?答案是仍然存在重复转账的风险,即查询接口的状态判断只有终态才是可信的,其他状态都是不可信,不能作为资金交易判断的关键依据,因为,存在类似可能的实现:此时后端系统在主db可能是已经转账成功,但备db还没同步到,而基于读写分离,此时查询接口调用的是备db的数据。另外使用方法3,通过对账后再决定是否需要重新转账,这个是可行的,但存在用户体验的问题,一般对账都是隔天T+1进行,也就是说要等到隔天才能确认是否需要进行重新转账。

        综上,为了更好的支持交易系统写接口的可重入性,在接口的设计和实现中,需要有一定的方案考虑,重入的关键变量集合很多,不同的业务可能有不同的考虑和设计,本文重点讲解基于订单号的重入设计,一方面是这是最常见的重入判断变量,另外一方面,该方法因为简单,通用性较强,具有很好的适配性。

       在交易接口中,一般服务调用方调用某个交易系统的时候,都会传入调用方的唯一识别码,一般就是业务订单号,或者唯一序列号等,它是标明本次交易操作的唯一编码,该编码不同代表不同的交易,相同则表示是同一个交易操作,而服务提供方通过判断该编码进行判断该请求是否已经处理过,从而到达重入的效果。

方案一,基于外部业务订单号的可重入接口的设计

      该方案的特点是,服务调用方每次调用交易系统的接口时候,必须自己确保生成一个唯一的订单号(或者在某个比较长的时间段内唯一也可以),然后作为交易系统接口调用的一个关键参数输入;交易系统收到该请求,为了保证可重入性,会以该外部订单号作为唯一健在db建立跟自身内部订单号的映射关系,大概如下:

                                            图1:基于外部业务订单号的映射表

建立了这个关系后,每次调用该接口,会首先插入该映射关系,若前面已经调用过,则外部业务订单号会因为唯一健冲突导致插入失败,此时,重新检查本次请求和上次请求的关键变量是否一致,若一致则返回接口重入,否则提示接口错误。

  图2:基于外部业务订单号的关键调用流程

         该方法的关键点是:1,外部服务调用方只需要调用一次接口即可;2,调用方需要自己生成并保障业务订单号的唯一性;3,服务提供方,需要维护以外部业务订单号为唯一健的订单映射表,由于不同调用方的业务订单号规则不统一,使得该映射表的数据不够规范,且无法实现按日期的归档等操作。

总之,该方法的订单映射关系维护的责任在服务提供方,而不是服务的调用方。

方案二,基于内部订单号的可重入接口的设计

        方案一虽能够解决接口重入的实现问题,但在实际操作中,仍然不够完美,主要在于随着时间的推进和不同调用方的订单规则不统一,使得订单映射db的维护变成一个问题,比如,累计到一定时段,订单映射表的数据是否可以删除归档?假如把2年前的删除归档,那么2年前的订单调用方不小心这个时候又调用过来,那么是认为是重入还新订单?此外,由于外部业务订单号不一定有时间的信息,因此也无法判断该订单属于什么时候,只能依靠存储的记忆,类似等等的弊端逐步的暴露出来。第2个问题是,这个订单映射的db有全局性的要求,随着云化和分布式的部署,需要对该db进行单独的处理。那么有没有更好的办法呢?方案一的一个问题是外部业务订单号的规则不可控,使得存储映射关系变成一个比较麻烦的事情,那么如果把判断重入的订单号从不可控的外部业务订单号变成自主可控的内部订单号,是不是就更简单呢?内部订单号的规则可以按照自己的规则进行制定,比如位数的统一,埋入时间信息和校验信息,埋入各种业务规则的信息等,然后基于内部订单号进行重入,其实可以去掉独立维护的订单映射关系表了,仅仅根据内部订单号的路由规则在订单表里面设定为UK即可保证,此外,由于埋入了时间信息,可以根据时间维度进行后续的订单db数据的归档,使得维护成本极大的降低。

       为了实现这个能力,服务提供方需要单独提供一个内部订单号(交易单号)的申请接口,服务调用方在调用交易接口之前,先调用该订单号申请接口,申请到订单号后跟自己的业务订单号进行绑定(保障自己业务订单号和该交易订单号的一一映射),然后以该新申请的交易订单号作为重入的关键变量调用交易接口。

 图3:基于内部订单号的关键调用流程

       该方法的关键点是:1,外部服务调用方需要调用两次接口,但由于第一个单号申请接口及其轻量,所以成本比较低;2,调用方需要自己绑定业务单号和新申请的交易单号;3,服务提供方,需要提供两个接口,但可以去掉独立维护的订单映射表。

总之,该方法的订单映射关系维护的责任在服务的调用方,而不是服务的提供方。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

基于订单号可重入的交易系统接口设计探讨 的相关文章

随机推荐

  • ROS 程序初读一(gps_driver)

    先来看到 launch 文件夹 xff0c 有三个 launch 文件 xff0c 也不知道从哪看起 xff0c 就从第一个看看先 第一个文件为 gps data get launch xff0c 内容如下 lt launch gt lt
  • 什么是SLO?

    Short term Liquidity Operation即短期流动性调节工具 SLO以7天期以内短期回购为主 xff0c 遇节假日可适当延长操作期限 xff0c 采用市场化利率招标方式开展操作 SLO原则上在公开市场常规操作的间歇期使用
  • 21.6.7爬虫日志

    一 爬虫的目的 采集数据 xff0c 为软件服务 xff01 xff01 那么数据从那儿来 xff1f 都是从生活中来的 xff01 xff01 1 手工采集 可以采集数据 xff0c 但是操作效率低下 2 内部数据 公司内部数据 xff0
  • 什么是自贸区?什么是离岸债券?

    1 自由贸易区 中国自由贸易区是指在国境内关外设立的 xff0c 以优惠税收和海关特殊监管政策 为主要手段 xff0c 以贸易自由化便利化为主要目的的多功能经济性特区 自由贸易区有两个本质上存在差异很大的概念 xff1a 一个是FTA xf
  • 什么是SLO?

    SLO xff1a 短期流动性调节工具 xff08 Short termLiquidityOperations xff09 每周二 周四 xff0c 央行一般都会进行公开市场操作 xff0c 目前最主要的是回购操作 回购操作又分成两种 xf
  • strcpy、strncpy与memcpy的区别与使用方法

    strcpy strncpy 与memcpy 的区别与使用方法 strcpy strncpy memcpy这三个C语言函数我们在主机代码编写中会很频繁的使用到 xff0c 但是三个函数的区别 使用时该注意什么还是有必要说下的 本文参考 C
  • C语言:存取结构体成员的点运算符(.)和箭头运算符(->)的区别

    一直以为这两个是没有什么区别的 xff0c 可以相互替换 xff0c 今天又翻了一下 C语言核心技术 xff0c 明白了其中的奥妙 相同点 xff1a 两个都是二元操作符 xff0c 其右操作符是成员的名称 不同点 xff1a 点操作符左边
  • DB2 命令行中如何执行sql脚本

    原文链接 xff1a http space itpub net 8231934 viewspace 584635 db2 61 gt connect to dbName user xxx using password db2 61 gt s
  • 性能测试知多少 --并发用户数与TPS之间的关系

    1 背景 在做性能测试的时候 xff0c 很多人都用并发用户数来衡量系统的性能 xff0c 觉得系统能支撑的并发用户数越多 xff0c 系统的性能就越好 xff1b 对TPS不是非常理解 xff0c 也根本不知道它们之间的关系 xff0c
  • ubuntu编译 opencv undefined referece to `cv::imread()`

    Ubuntu下编译一个C 43 43 文件 xff0c C 43 43 源程序中使用了opencv xff0c opencv的安装没有问题 xff0c 但是在编译的过程中出现如下错误 xff1a undefined reference to
  • 基于深度学习的3D pose estimation总结(包括几篇2D pose estimation)

    一 任务描述 给定一幅图或者是一段视频 xff0c 人体姿态估计就是恢复出其中的人体关节点位置的过程 二 挑战和难点 1 人体肢体运动较为灵活 xff1b 2 视角的变化 xff1b 3 附着物的变化 xff08 比如遮挡 xff0c 衣物
  • STM32的空闲中断

    最近发现了STM32的USART的空闲中断非常的舒爽 xff0c 但是在前期配置的时候会出现一些小问题导致没有办法进入终中断或者是一直空闲中断 xff0c 现将它记下来 xff0c 给各位和自己留一个参考 xff1a 1 不进入中断 我是这
  • Github上最受欢迎的7个开源AI机器学习框架

    在过去的几年中 xff0c 人工智能正在占领技术的许多领域 来自不同背景的开发人员最终意识到了AI为他们带来的机遇 xff0c 而不管他们的需求如何 在今天的文章中 xff0c 我们列出了7种最佳的开源AI 机器学习系统和框架 1 Tens
  • ubuntu更换shell

    ubuntu更换shell zsh配置 span class token comment 安装zsh span span class token function sudo span span class token function ap
  • 网络调试助手NetAssist的使用

    一 使用场景 xff1a 项目定制需求 xff1a 前端的车载终端把gps 报警信息 报警图片 其他检测数据发往约定的第三方服务器 xff0c 车载终端通过公网 xff08 SIM拨号或者有线网 xff09 以udp或者tcp连接服务器 x
  • vlc代码分析(4)——mpgv的demux

    Mpgv c 是对mpeg vedio的解码部分 xff0c 从demux开始 xff0c 到sample到输出 其中 xff0c 核心部分是函数ParseMPEGBlock 两种数据格式 xff1a video format 是video
  • 关于使用CMT2300A FIFO缓存区间设置为64Byte的问题

    首先请看 xff0c CMT2300A 是什么产品 xff0c 或者说是 模组吗 xff1f 请看介绍 xff1a https blog csdn net sishuihuahua article details 105095994 以及R
  • 不合理超时设置带来的“坑”

    在后台服务的实现中 xff0c 我们通过基于TCP UDP协议封装起来的RPC机制实现了跟不同系统的通信 xff0c 进而协同各个系统完成一系列业务流程和功能的执行 xff0c 在这个过程中 xff0c 每个参与合作的子系统都有自己的能力描
  • 以太坊的三种同步模式

    全同步 xff1a 获取区块链所有区块的header和body xff0c 并校验其中的每一笔交易 xff0c 需要下载所有的区块数据信息 xff0c 同步速度最慢 xff0c 但是数据最全 xff1b 快速同步 xff1a 获取区块链所有
  • 基于订单号可重入的交易系统接口设计探讨

    基于订单号可重入的交易系统接口设计探讨 在交易系统的设计和实现中 xff0c 接口的可重入性设计是及其关键的 xff0c 可重入性也叫接口操作的冥等性保障 xff0c 那么什么叫冥等性呢 xff1f 在交易系统中 xff0c 为什么需要这个