商品购买过程中,库存的抵扣过程是怎样的?如何防止超卖?

在商品购买的过程中,库存的抵扣过程,一般操作如下:

1、select根据商品id查询商品的库存。

2、根据下单的数量,计算库存是否足够,如果存库不足则抛出库存不足的异常,如果库存足够,则减去扣除的库存得到最新的库存剩余值。

3、set设置最新的库存剩余值。

上述过程的伪代码如下:

// 根据商品id获取商品剩余库存
select stock_remaing from stock_table where id=${goodsId};// 操作库存
// 比较库存
if(stock_remaing <quantity){// 抛出库存不足的异常
}
else{// 抵扣以后的库存值int new_stock=stock_remaing - quantity;
}// 根据商品id设置计算后的库存
update stock_table  set stock_remaing =${new_stock} id=${goodsId};

并发修改数据库存超卖

如果数据库事务的隔离级别不是串行化(serializable),根据事务的特性,在并发修改的时候,可能会出现写覆盖的问题。

假设,商品的剩余库存stock_remaing 为100,客户A下单20,客户B下单30,在并发扣库存的时候,可能存在超卖。如果客户A和客户B同时获取剩余库存为100,则会出现事务后提交的值会覆盖前一个客户提交的值,有可能剩余的库存是80或者70。

流程如下:

图片

加锁更新存库

为了在事务控制中,防止写覆盖,你会想到使用select for update的方式,将该商品的库存锁住,然后执行余下的操作。

流程如下:

图片

以上,使用悲观锁方式,在分布式服务中,如果并发情况比较高的时候,扣减库存的操作是串行操作,效率很低。

使用乐观锁的方式更新

在更新的时候,使用(CAS+版本号更新)+重试条件(重试次数或者重试时间限制)乐观锁的方式更新库存。此时,如果,客户A和客户B同时读取到库存剩余100,在更新的时候,有一个操作会失败。

流程如下:

图片

该种方式可以大大提高并发性,也可以保证数据的一致性;通过重试次数和重试时间的条件控制,可以防止过多的重试带来的数据库压力。

可以使用直接递减的方式执行么?

在抵扣库存的时候,有的人提议不执行select,计算,set三段式的操作,直接扣减的方式,并且对于扣减到小于零的情况作了判断。伪代码如下:

update stock_table set remaing_stock=remaing_stock-${quantity} 
where id =商品id
and remaing_stock>${quantity};

在分布式服务调用中,因为网络异常,获取服务器异常,可能在微服务调用时,存在服务重试。例如,场景的网关超时,服务重试机制。此时,该种方式不满足幂等性,而存在多扣的情况。例如,同一用户扣减库存时,服务重试,极端情况下,该用户扣减库存操作执行多次,则就出现了商品超卖。

可以使用redis进行库存的抵扣么?

答案是可以使用redis的事务性扣减余额,但在CAS机制上比mysql没有优势,高性能是因为其内存存储的原因,带来的副作用是数据有丢失风险。

最后说一句(求关注!别白嫖!)

如果这篇文章对您有所帮助,或者有所启发的话,求一键三连:点赞、转发、在看。

关注公众号:woniuxgg,在公众号中回复:笔记  就可以获得蜗牛为你精心准备的java实战语雀笔记,回复面试、开发手册、有超赞的粉丝福利!

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

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

相关文章

mysql+keepalive+lvs搭建的数据库集群实验

前提条件&#xff1a;准备5台计算机&#xff0c;且网络互通 1、客户端 yum groups -y install mariadb-client ip 192.168.0.5 2、lvs1 yum-y install ipvsadm keepalived ip 192.168.0.1 keepalivedvip 192.168.0.215 /etc/hosts 解析192.168.0.1 主机名 3、lvs2 yum-y i…

前视声呐目标识别定位(五)-代码解析之修改声呐参数

前视声呐目标识别定位&#xff08;一&#xff09;-基础知识 前视声呐目标识别定位&#xff08;二&#xff09;-目标识别定位模块 前视声呐目标识别定位&#xff08;三&#xff09;-部署至机器人 前视声呐目标识别定位&#xff08;四&#xff09;-代码解析之启动识别模块 …

DHT11温湿度传感器使用视频教程分享

下载地址&#xff1a; 温湿度计(STCDHT11): https://url83.ctfile.com/d/45573183-60623983-9b7f6c?p7526 (访问密码: 7526)

Java常用类和基础API

文章目录 1. 字符串相关类之不可变字符序列&#xff1a;String1.1 String的特性1.2 String的内存结构1.2.1 概述1.2.2 练习类型1&#xff1a;拼接1.2.3 练习类型2&#xff1a;new1.2.4 练习类型3&#xff1a;intern() 1.3 String的常用API-11.3.1 构造器1.3.2 字符串对象的比较…

解决酷狗官网无法播放音乐问题

播放歌曲页面无法播放歌曲&#xff0c;有CORS错误&#xff0c;困扰我很久了。 谷歌浏览器优雅的关闭cors跨域_浏览器关闭跨域-CSDN博客 "C:\Program Files\CatsxpSoftware\Catsxp-Browser\Application\catsxp.exe" --disable-web-security --user-data-dirE:\catsxp…

【学习笔记】java项目—苍穹外卖day10

文章目录 苍穹外卖-day10课程内容1. Spring Task1.1 介绍1.2 cron表达式1.3 入门案例1.3.1 Spring Task使用步骤1.3.2 代码开发1.3.3 功能测试 2.订单状态定时处理2.1 需求分析2.2 代码开发2.3 功能测试 3. WebSocket3.1 介绍3.2 入门案例3.2.1 案例分析3.2.2 代码开发3.2.3 功…

Fusion360修改嘉立创EDA专业版生成的3D外壳文件

需要第三方软件的原因 嘉立创EDA专业版生成电路板的3D外壳文件是比较快捷的&#xff0c;但如果侧面精密开孔或者添加其它非常规的元素还是有些局限。嘉立创EDA专业版可以把3D外壳文件导出&#xff0c;这就大大方便了第三方软件的修改。 本文是利用Fusion360修改3D外壳文件&…

Waifu2x:使用深度卷积神经网络的动漫风格艺术的图像超分辨率

Github网址&#xff1a;nagadomi/waifu2x&#xff1a;动漫风格艺术的图像超分辨率 (github.com) 该项目主要讲述的是如何利用预训练的深度学习模型来达到无损扩大收缩和去噪&#xff0c;对于一般训练图像的小伙伴应该很清晰图像经常要通过resize操作固定大小&#xff0c;然后c…

某华为hr擅自给我报名机

某华为hr擅自报名机考 上周&#xff0c;牛客网一位同学爆料&#xff1a; ❝ 今年一月份&#xff0c;华为一位 HR 通过某招聘网站联系到他&#xff0c;然后通过该 HR 加上了业务工程师的微信。随后&#xff0c;该工程师在「经过他本人同意」的情况下&#xff0c;在系统录入了他的…

CSGO比赛赛事大科普,Major并不是一个赛事!

关于CSGO比赛&#xff0c;有很多人都听过许多相关名词&#xff1a;Major、Minor、IEM、EPL、ESL ONE、Dreamhack、ESEA、Blast、EPICENTER等等&#xff0c;但大家有没有想过这些名词所代表的含义呢&#xff1f; Major、Minor严格意义上说&#xff0c;Major、Minor本身并不是赛事…

深入浅出 -- 系统架构之分布式架构

​​​​​​分布式架构&#xff1a; 根据业务功能对系统做拆分&#xff0c;每个业务功能模块作为独立项目开发&#xff0c;称为一个服务。 当垂直应用越来越多时&#xff0c;应用之间的交互不可避免&#xff0c;可将共用的基础服务或核心模块抽取出来作为独立服务&#xff0c…

接口练习题目

练习一 1、声明接口Eatable&#xff0c;包含抽象方法public abstract void eat(); 2、声明实现类中国人Chinese&#xff0c;重写抽象方法&#xff0c;打印用筷子吃饭 3、声明实现类美国人American&#xff0c;重写抽象方法&#xff0c;打印用刀叉吃饭 4、声明实现类印度人Indi…

GDPU 竞赛技能实践 天码行空6

&#x1f4d6; 敌兵布阵 C国的死对头A国这段时间正在进行军事演习&#xff0c;所以C国间谍头子Derek和他手下Tidy又开始忙乎了。A国在海岸线沿直线布置了N个工兵营地,Derek和Tidy的任务就是要监视这些工兵营地的活动情况。由于采取了某种先进的监测手段&#xff0c;所以每个工…

使用PostgreSQL中的隐式转换解决,MybatisPlus插入数据库时的类型不一致的问题

使用PostgreSQL中的隐式转换解决,MybatisPlus插入数据库时的类型不一致的问题 问题描述 鄙人在使用 MybatisPlus插件开发一个SpringBoot项目时, 遇到数据库中employee表与Java实体对象中某个属性的类型不一致, 导致插入数据库失败. 具体问题截图如下: 具体原因在于, Java实体…

Java入门教程||Java 多线程编程

Java 多线程编程 Java 给多线程编程提供了内置的支持。一个多线程程序包含两个或多个能并发运行的部分。程序的每一部分都称作一个线程&#xff0c;并且每个线程定义了一个独立的执行路径。 多线程是多任务的一种特别的形式。多线程比多任务需要更小的开销。 这里定义和线程…

usbserial驱动流程解析_Part1_主要函数

本系列解析usbseiral ko的源码&#xff0c;记录主要函数&#xff0c;调用流程&#xff0c;USB一端和串口一端的注册流程&#xff0c;本节简介主要函数以及替换规则。 首先&#xff0c;usbserial是USB转串口驱动的一个基础模板&#xff0c;其中有许多默认函数&#xff0c;他们的…

书生·浦语训练营二期第二次课后作业

文章目录 基础作业使用 InternLM2-Chat-1.8B 模型生成 300 字的小故事 进阶作业熟悉 huggingface 下载功能完成 浦语灵笔2 的 图文创作 及 视觉问答 部署图文创作视觉问答 完成 Lagent 工具调用 数据分析 Demo 部署 作业详细操作步骤见第二次课笔记&#xff1a;https://blog.cs…

CSS层叠样式表学习(字体属性)

&#xff08;大家好&#xff0c;今天我们将继续来学习CSS字体属性的相关知识&#xff0c;大家可以在评论区进行互动答疑哦~加油&#xff01;&#x1f495;&#xff09; 三、CSS字体属性 CSS Fonts(字体)属性用于定义字体系列、大小&#xff0c;粗细&#xff0c;和文字样式(如斜…

list的常用接口底层实现与介绍

目录 概念&#xff1a; list的基本结构&#xff1a; list的迭代器⭐❤&#xff1a; 自定义类型的完善&#xff1a; const的迭代器&#xff1a; insert erase&#xff1a; size empty push_back 、push_front 、pop_back、pop_front swap 、operator 析构函数…

什么是CSGO游戏搬砖及游戏搬砖注意事项?

CSGO市场是指《反恐精英&#xff1a;全球攻势》游戏内的物品交易市场。玩家可以在这个市场上买卖各类虚拟物品&#xff0c;包括武器皮肤、刀具、手套等。CSGO市场的价格是由供需关系、稀有度、流行度等多个因素影响的。 一般来说&#xff0c;稀有度较高或者比较受欢迎的物品价格…