使用乐观锁解决超卖问题

目录

什么是超卖?

 乐观锁和悲观锁的定义

悲观锁:

乐观锁:

乐观锁的实现方式

1.版本号

 2.CAS法


什么是超卖?

举个例子:订单系统中,用户在执行下单操作时,可能同一时间有无数个用户同时下单,当a用户的请求查询当前商品库存时,发现当前的商品剩余5件,在执行生成订单并减少库存时,线程切换了,此时b用户执行了查询操作,发现还是剩余5件,并进行了下单操作,这样就导致了这件商品被卖掉了两次

正常的情况如下:

 发生线程切换,产生异常的情况:

 乐观锁和悲观锁的定义

悲观锁:

认为线程安全问题一定会发生,因此在操作数据之前先获取锁,确保线程串行执行。例如SynchronizedLock都属于悲观锁

乐观锁:

认为线程安全问题不一定会发生,因此不加锁,只是在更新数据时去判断有没有其它线程对数据做了修改。

如果没有修改则认为是安全的,自己才更新数据。

如果已经被其它线程修改说明发生了安全问题,此时可以重试或异常

乐观锁的实现方式

1.版本号

给商品加上版本号字段,如果查询到就让其version=1,在修改执行的时候,先判断版本号是不是正确的,如果是让其版本号发生变化,并执行扣减,如果不是就说明当前商品已经卖出

       

 2.CAS法

CAS流程如下:

  1. 获取目标内存位置的当前值。
  2. 检查当前值是否与预期值相等。
  3. 如果相等,则将新值写入目标内存位置;否则,放弃写入操作,可能是重新读取当前值并重试整个CAS操作。

 比如当前的订单系统中,就可以使用查询到的库存作为预期值,修改的时候进行判定,如果是库存和第一次查询到的一样就执行,不一样就取消执行,这样就能够保证原子性

 具体实现只需要更改sql语句就可以做到

UPDATE users
SET stock=stock-1
WHERE id = 10 and stock = #{第一次查询到的库存};

 

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

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

相关文章

linux静态库与动态库

1、动态库和静态库概念 Linux中的库分为动态库和静态库。 静态库(.a):库文件以.a为后缀,程序在编译链接时把库的代码链接到可执行文件中(将需要的库函数拷贝一份到代码中)。程序运行时不需要再跳转到静态…

vue3报错

这是因为eslint对代码的要求严格导致的,可以在package.json里面删掉"eslint:recommended",然后重启就可以正常运行了

电影院订票选座网站小程序开发(java开源)

搭建一个电影院订票选座网站小程序需要掌握Java语言和相关的Web开发技术,同时需要使用开源框架和库来实现。以下是一个基本的步骤指南: 确定技术栈 首先,需要确定使用的技术栈,以便更好的开展工作。 设计数据库 设计数据库需要…

畜牧虚拟仿真 | 鱼授精过程VR模拟演练系统

随着科技的发展,虚拟现实(VR)技术逐渐渗透到各个领域,为人们提供了更加真实、直观的体验。在动物养殖教育领域,鱼授精过程VR模拟演练系统正成为一种新的教学手段,它能够帮助人们更好地理解和掌握鱼授精的操作技巧,从而…

Maven进阶2 -- 私服(Nexus)、私服仓库分类、资源上传和下载

目录 私服是一台独立的服务器,用于解决团队内部的资源共享与资源同步问题。 1.Nexus Nexus是sonatype公司的一款maven私服产品。 下载地址 启动 nexus.exe /run nexus 访问 & 登录 2.私服仓库分类 3.资源上传和下载 本地仓库上传和访问资源需要进行配置。…

章节2:客户端的Cookie

章节2:客户端的Cookie 无状态的影响 现实:每个请求都是独立的 需求:保持会话 cookie内容 key/value 格式,例如: namewuya id99 islogin1 cookie怎么产生 Cookie格式 Set-Cookie:第一次访问&#…

java版工程项目管理系统源码+系统管理+系统设置+项目管理+合同管理+二次开发em

​ 鸿鹄工程项目管理系统 Spring CloudSpring BootMybatisVueElementUI前后端分离构建工程项目管理系统 1. 项目背景 一、随着公司的快速发展,企业人员和经营规模不断壮大。为了提高工程管理效率、减轻劳动强度、提高信息处理速度和准确性,公司对内部…

IP路由基础+OSPF 基础

IP路由 RIB与FIB RIB:Routing Information Base,路由信息库 ,路由器的控制平面 FIB:Forwarding Information Base,转发信息库,路由器的数据平面 路由信息库主要是记录直连路由以及协议宣告的路由信息&am…

如何给a-table增加列宽拖动功能

对于table的列宽设置 相信用过的人都知道,想要设置得很完美,几乎是不现实的,因为总有数据或长或短,那我们应该如何优化它呢?那便是让用户自行拖动列宽,从而能看全table的数据,但是对于antd-vue …

恒运资本:股票印花税下降有什么影响?什么原因导致下降?

在进行股票教育过程中是需求收取必定的手续费的,比如说买卖佣钱、印花税、过户费等等。那么股票印花税下降有什么影响?什么原因导致下降?下面就由恒运资本为大家剖析: 股票印花税下降有什么影响? 1、对于企业&#xf…

vscode运行python报错:ModuleNotFoundError:No module named ‘xxx‘

在乌班图上使用pycharm的时候,pycharm总是莫名其妙卡死,又说是搜狗输入法的锅,又说别的原因,一气之下不用pycharm,转到vscode上,没想到出现了如下报错。 就是vscode在运行python的时候,自定义模块的调用无…

【C语言】经典题目(四)

HI,大家好~😝😝这是一篇C语言经典题目的博客。 更多C语言经典题目及刷题篇,可以参考: 🌸 【C语言】经典题目(一) 🌸 【C语言】经典题目(二) 🌸 【C语言】经典题目(三) 🌸…

vue3中的自定义指令用法

我们都知道vue2中自定义指令全局和局部是这样写的 局部: 全局: 可vue3写法发生改变,如下: 全局: 局部:

音视频 FFmpeg命令行搭建

文章目录 一、配置二、测试 一、配置 以FFmpeg4.2.1 win32为例 解压ffmpeg-4.2.1-win32-shared.zip 拷⻉可执⾏⽂件到C:\Windows拷⻉动态链接库到C:\Windows\SysWOW64 注:WoW64 (Windows On Windows64)是⼀个Windows操作系统的⼦系统,被设计⽤来处理许…

【网络】自定义协议 | 序列化和反序列化 | Jsoncpp

本文首发于 慕雪的寒舍 以tcpServer的计算器服务为例,实现用jsoncpp来进行序列化和反序列化 阅读本文之前,请先阅读 自定义协议 | 序列化和反序列化 | 以tcpServer为例 1.安装jsoncpp 我所用的系统是centos7.6,先用下面的命令查找相关的包 …

图的遍历之 深度优先搜索和广度优先搜索

深度优先搜索的图文介绍 1. 深度优先搜索介绍 图的深度优先搜索(Depth First Search),和树的先序遍历比较类似。 它的思想:假设初始状态是图中所有顶点均未被访问,则从某个顶点v出发,首先访问该顶点,然后依次从它的各…

Element组件浅尝辄止2:Card卡片组件

根据官方说法: 将信息聚合在卡片容器中展示。 1.啥时候使用?When? 既然是信息聚合的容器,那场景就好说了 新建页面时可以用来当做页面容器页面的某一部分,可以用来当做子容器 2.怎样使用?How? //Card …

分布式应用:Zabbix代理服务器与SNMP监控

目录 一、理论 1.分布式监控 2.Zabbix代理服务器部署 3.配置 agent 使用 proxy 4.设置 Zabbix-SNMP 监控 二、实验 1.Zabbix代理服务器部署 2.配置 agent 使用 proxy 3.设置 Zabbix-SNMP 监控 三、总结 一、理论 1.分布式监控 (1)作用&#x…

Docker安装Mysql、Redis、nginx、nacos等环境

相关系列文章: 1、DockerHarbor私有仓库快速搭建 2、DockerJenkinsHarbor 1、服务器 Ip部署内容说明192.168.88.7Docker、Mysql、redis、nacosnode1192.168.88.8Docker、Mysql、redis、nacosnode2192.168.88.9Docker、redis、nacos、nginxnode3 2、安装PXC8.0 Mys…

PHP实现在线进制转换器,10进制,2、4、8、16、32进制转换

1.接口文档 2.laravel实现代码 /*** 进制转换计算器* return \Illuminate\Http\JsonResponse*/public function binaryConvertCal(){$ten $this->request(ten);$two $this->request(two);$four $this->request(four);$eight $this->request(eight);$sixteen …