当前位置:首页 > 娱乐 >

非重复下单什么意思(重复下单有什么弊端)

来源:原点资讯(m.360kss.com)时间:2024-11-30 17:26:58作者:YD166手机阅读>>

一、问题背景

最简单的:DB 事务。如创建订单时,同时往订单表、订单商品表插数据,这些 Insert 须在同一事务执行。

Order 服务调用 Pay 服务,刚好网络超时,然后 Order 服务开始重试机制,于是 Pay 服务对同一支付请求,就接收到了两次,而且因为轮询负载均衡算法,落在了不同业务节点!所以一个分布式系统接口,须保证幂等性。

二、如何避免重复下单

前端页面也可直接防止用户重复提交表单,但网络错误会导致重传,很多RPC框架、网关都有自动重试机制,所以重复请求在前端侧无法完全避免!问题最后还是如何保证服务接口的幂等性。

2.1 如何判断请求是重复的
  • 插入订单前,先查一下订单表,有无重复订单? 难以用SQL条件定义到底什么是“重复订单”
  • 订单的用户、商品、价格一样就是重复订单? 万一这用户就是连续下了俩一模一样订单呢?

所以保证幂等性要做到:

2.1.1 每个请求须有唯一标识

比如订单支付请求,得包含订单 id,一个订单 id 最多只能成功支付一次。

2.1.2 每次处理完请求后,须有记录标识该请求已被处理

在 MySQL 中记录一个状态字段。如支付之前记录一条这个订单的支付流水。

2.1.3 每次接收请求时,判断之前是否处理过

若有一个订单已支付,就肯定已有一条支付流水。若重复发送这个请求,则此时先插入/支付流水,发现 orderId 已存在,唯一约束生效,报错重复 Key。就不会再重复扣款。

在往 DB 插记录时,一般不提供主键,而由 DB 在插入时自动生成。这样重复的请求就会导致插入重复的数据。MySQL 的主键自带唯一性约束,若在一条 INSERT 语句提供主键,且该主键值在表中已存在,则该条 INSERT 会执行失败。因此可利用 DB 的“主键唯一约束”,在插数据时带上主键,以此实现创建订单接口的幂等性。

给 Order 服务添加一个“orderId 生成”的接口,无参,返回值就是一个【全局唯一】订单号。在用户进入创建订单页面时,前端页面先调用该 orderId 生成接口得到一个订单号,在用户提交订单时,在创建订单的请求中携带该订单号。

该订单号其实就是订单表的主键,于是,重复请求中带的都是同一订单号。订单服务在订单表中插入数据的时候,执行的这些重复 INSERT 语句中的主键,也都是同一个订单号。而 DB 唯一约束保证,只有一次 INSERT 执行成功。

实际要结合业务,如使用 Redis,用 orderId 作为唯一K。只有成功插入这个支付流水,才可执行扣款。

要求是支付一个订单,须插入一条支付流水,order_id 建立一个唯一键。你在支付一个订单前,先插入一条支付流水,order_id 就已经传过去了。就能写一个标识到 Redis 中,set order_id payed,当重复请求过来时,先查 Redis 的 order_id 对应的 value,若为 payed 说明已支付,就别再重复支付!

然后再重复支付订单时,写尝试插入一条支付流水,DB 会报唯一键冲突,整个事务回滚。保存一个是否处理过的标识也可以,服务的不同实例可以一起操作 Redis。

非重复下单什么意思,重复下单有什么弊端(1)

若因重复订单导致插入 t_order 失败,则 Order 服务不要把该错误返给前端页面。否则,就可能出现用户点击创建订单按钮后,页面提示创建订单失败,而实际上订单创建成功了。

正确做法:这种 case,订单服务直接返回订单创建成功。

三、解决 ABA3.1 什么是 ABA

如订单支付后,seller 要发货,发货完成后要填个快递单号。假设 seller 填个 666,刚填完,发现填错了,赶紧再修改成 888。对订单服务,这就是 2 个更新订单的请求。系统异常时 666 请求到了,单号更成 666,接着 888 请求到了,单号又更新成 888,但是 666 更新成功的响应丢了,调用方没收到成功响应,自动重试,再次发起 666 请求,单号又被更新成 666了,这数据显然就错了!

非重复下单什么意思,重复下单有什么弊端(2)

3.2 解决方案

订单主表增加 version 列。每次查询订单时,版本号要随着订单数据返回给页面。页面在更新数据的请求中,把这个版本号作为更新请求的参数,带回给订单更新接口。

订单服务在更新数据的时候,需要比较订单的版本号是否和消息中的一致:

  • 不一致:拒绝更新数据
  • 一致:还需再更新数据的同时,将 version 1。“比较版本号、更新数据和版本号 1”的过程须在同一事务执行

UPDATE orders set tracking_number = 666, version = version 1 WHERE version = 8;

在这条 SQL 的 WHERE 条件中,version 值需要页面在更新的时候通过请求传进来。

通过该版本号,就能保证,从我打开这条订单记录开始,一直到我更新这条订单记录成功,期间没有其他人修改过该订单数据。若有,则 DB 中的 version 就会改变,那我的更新操作就会执行失败。我就只能重新查询新版本的订单数据,再尝试更新。

有了这个版本号,前文的 ABA 即有两个 case:

  • 把运单号更新为 666 成功,更新为 888 的请求带着旧版本号,就更新失败,页面提示用户更新 888 失败
  • 666 更新成功后,888 带着新版本号,888 更新成功。这时即使重试的 666 请求再来,因为它和上一条 666 请求带相同版本号,上一条请求更新成功后,这个版本号已经变了,所以重试请求的更新必然失败

无论哪种情况,DB 中的数据与页面上给用户的反馈都是一致的。这就实现了幂等更新且避免 ABA。

非重复下单什么意思,重复下单有什么弊端(3)

防止订单重复支付订单支付流程

我们来看看,电商订单支付的简要流程:

非重复下单什么意思,重复下单有什么弊端(4)

首页 1234下一页

栏目热文

空单下单什么意思

空单下单什么意思

如今最火的短视频平台是抖音,如今越来越多的抖音用户开始在此平台上带货赚钱,而那些开着抖音小店的抖音用户也不在少数,对于抖...

2024-11-30 16:48:28查看全文 >>

d 类下单什么意思(大神说的下单是什么意思)

d 类下单什么意思(大神说的下单是什么意思)

作者:faryrong,腾讯CSIG后台开发工程师| 导语最近看了一本书《解构-领域驱动设计》,书中提出了领域驱动设计统...

2024-11-30 17:23:07查看全文 >>

代客下单是什么意思(代客订单什么意思)

代客下单是什么意思(代客订单什么意思)

娃哈哈陷入关店风波最近,娃哈哈奶茶加盟商的维权事件在线上线下闹得沸沸扬扬,娃哈哈的奶茶业务一度陷入“关店风波”。不少加盟...

2024-11-30 17:02:18查看全文 >>

恶意下单指的是什么意思(无限下单是什么意思)

恶意下单指的是什么意思(无限下单是什么意思)

高师傅住在杭州萧山同兴村他介绍今年五月份他女儿的班级需要采购一些儿童节表演服装因为以前的儿童节都是自己负责采购的对各方面...

2024-11-30 17:07:47查看全文 >>

无脑下单是什么梗(无脑下单是什么意思)

无脑下单是什么梗(无脑下单是什么意思)

抖音无脑下单什么梗?很多的热梗和好玩的事情在抖音上出现,无脑下单也是其中之一,用离开讽刺哪些无良的商家,那么这个梗代表的...

2024-11-30 17:22:20查看全文 >>

放心下单是什么意思(代客下单是啥意思)

放心下单是什么意思(代客下单是啥意思)

扬子晚报网12月26日讯(记者 李冲)春运即将开始,到哪里购票成为很多人关心的问题。随着网络购票的普及,在线旅游平台也成...

2024-11-30 17:24:54查看全文 >>

晚点喊下单什么意思(代客下单是啥意思)

晚点喊下单什么意思(代客下单是啥意思)

你的购物车藏着哪些不为人知的秘密?揭秘‘先用后付’背后的消费陷阱,别让便利成为负担![了解真相]‘先用后付’,听起来很美...

2024-11-30 17:09:05查看全文 >>

无痕下单什么意思(下单记忆什么意思)

无痕下单什么意思(下单记忆什么意思)

图片由腾讯元宝AI生成。 预订界面的“订后即焚”功能说明。 近期,山东一位网友在某社交媒体上分享了自己在同程旅行预订酒店...

2024-11-30 17:22:35查看全文 >>

一招有效去除黑屁屁(去除臀部黑印的药膏)

一招有效去除黑屁屁(去除臀部黑印的药膏)

原创:巍子原创很多年轻的女屁股两边儿有两块儿黑印儿,怎么去除?夏天很多女性特别想穿上漂亮的泳衣去游泳或者去海边玩,但是有...

2024-11-30 16:56:49查看全文 >>

太阳的化学成分怎么测(太阳的重量是怎么测量的)

太阳的化学成分怎么测(太阳的重量是怎么测量的)

2016年,中国科学院光电技术研究所太阳高分辨力成像研究团队成功研制了当时世界上通道数最多的太阳大气多波段层析成像系统,...

2024-11-30 17:25:35查看全文 >>

文档排行