面试官问:如何防超卖,有几种实现方式

面试官问:如何防超卖,有几种实现方式

大家好,又见面了,我是全栈君。

场景

面试官问:如何防超卖,有几种实现方式

第一种方法 悲观锁

悲观并发控制(又名 “悲观锁”,Pessimistic Concurrency Control,缩写 “PCC”)是一种并发控制的方法。它可以阻止一个事务以影响其他用户的方式来修改数据。如果一个事务执行的操作读某行数据应用了锁,那只有当这个事务把锁释放,其他事务才能够执行与该锁冲突的操作。

悲观并发控制主要用于数据争用激烈的环境,以及发生并发冲突时使用锁保护数据的成本要低于回滚事务的成本的环境中。

竹子,公众号:码农编程进阶笔记php程序员面试题(偏中级面试题)

简而言之,悲观锁主要用于保护数据的完整性。当多个事务并发执行时,某个事务对数据应用了锁,则其他事务只能等该事务执行完了,才能进行对该数据进行修改操作。

update goods set num = num - 1 WHERE id = 1001 and num > 0

假设现在商品只剩下一件了,此时数据库中 num = 1;

但有 100 个线程同时读取到了这个 num = 1,所以 100 个线程都开始减库存了。

但你会最终会发觉,其实只有一个线程减库存成功,其他 99 个线程全部失败。

需要注意的是,FOR UPDATE 生效需要同时满足两个条件时才生效:

  • 数据库的引擎为 innoDB

  • 操作位于事务块中(BEGIN/COMMIT)

悲观锁采用的是「先获取锁再访问」的策略,来保障数据的安全。但是加锁策略,依赖数据库实现,会增加数据库的负担,且会增加死锁的发生几率。此外,对于不会发生变化的只读数据,加锁只会增加额外不必要的负担。在实际的实践中,对于并发很高的场景并不会使用悲观锁,因为当一个事务锁住了数据,那么其他事务都会发生阻塞,会导致大量的事务发生积压拖垮整个系统。


第二种办法 乐观锁

select version from goods WHERE id= 1001;

update goods set num = num - 1, version = version + 1 WHERE id= 1001 AND num > 0 AND version = @version(上面查到的version);

这种方式采用了版本号的方式,其实也就是 CAS 的原理。

假设此时 version = 100, num = 1; 100 个线程进入到了这里,同时他们 select 出来版本号都是 version = 100。

然后直接 update 的时候,只有其中一个先 update 了,同时更新了版本号。

那么其他 99 个在更新的时候,会发觉 version 并不等于上次 select 的 version,就说明 version 被其他线程修改过了。那么我就放弃这次 update


第三种方法 redis 消息队列

在秒杀的情况下,高频率的去读写数据库,会严重造成性能问题。所以必须借助其他服务, 利用 redis 的单线程预减库存。比如商品有 100 件。那么我在 redis 存储一个 k,v。例如

每一个用户线程进来,key 值就减 1,等减到 0 的时候,全部拒绝剩下的请求。

那么也就是只有 100 个线程会进入到后续操作。所以一定不会出现超卖的现象。


第四种办法 redis 分布式锁

$expire = 10;//有效期10秒
$key = 'lock';//key
$value = time() + $expire;//锁的值 = Unix时间戳 + 锁的有效期
$lock = $redis->setnx($key, $value);
//判断是否上锁成功,成功则执行下步操作
if(!empty($lock))
{
//下单逻辑...
}

面试官问:如何防超卖,有几种实现方式

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/111437.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • Springboot + Openjpa 整合 GBase8s 实践「建议收藏」

    Springboot + Openjpa 整合 GBase8s 实践「建议收藏」本文我们将先来介绍JPA以及OpenJPA之间的关系,然后通过一个手把手的应用案例来讲述Springboot和Openjpa整合GBase8s。那么就让我们开始吧。JPAJPA(JavaPersistenceAPI)作为JavaEE5.0平台标准的ORM规范,将得到所有JavaEE服务器的支持。Sun这次吸取了之前EJB规范惨痛失败的经历,在充分吸收现有ORM框架的基础上,得到了一个易于使用、伸缩性强的ORM规范。从目前的开发社区的反应上看,JPA受到了极大…

  • 自动化测试之超厉害自动化录制工具介绍

    自动化测试之超厉害自动化录制工具介绍

  • 电脑蓝屏错误代码0x000000ED_电脑蓝屏0*000000ed怎么解决

    电脑蓝屏错误代码0x000000ED_电脑蓝屏0*000000ed怎么解决电脑蓝屏的原因很多,不同的电脑蓝屏显示的代码不同,对应的解决方法也不同。最近就有网友说自己的电脑蓝屏代码0x000000ed怎么办,不知道0x000000ed是什么意思。今天小编就教下大家修复电脑蓝屏代码0x000000ed的解决方法。0x000000ed蓝屏原因:说明I/0子系统试图加载到引导卷时失败。一般因为不正常断电导致的硬盘故障,从而导致启动时不能正常加载。具体的解决方法如下:1、先开机按f8看能否进入安全模式,能够进入的话,打开运行/输入CMD,键入命令chkdsk/f/r回…

  • 简单的Servlet结合Jsp实现请求和响应以及对doGet和doPost的浅析

    简单的Servlet结合Jsp实现请求和响应以及对doGet和doPost的浅析

  • MATLAB学习笔记 plotyy双y轴

    MATLAB学习笔记 plotyy双y轴一、线型设置:t=0:0.1:8;[ax,h1,h2]=plotyy(t,sin(t),t,cos(t));% plotyy(X1,Y1,X2,Y2):以左、右不同纵轴绘制X1-Y1、X2-Y2两条曲线。set(h1,’linestyle’,’-‘,’marker’,’o’,’color’,’r’);set(h2,’linestyle’,’:’,’marker’,’x’,’color’…

  • Jmeter断言-响应断言「建议收藏」

    Jmeter断言-响应断言「建议收藏」1:Jmeter断言-响应断言1.1:添加线程组1.2:添加http请求1.3:在http请求下添加“响应断言”1.4:添加查看结果树和Debug取样器1:断言成功的结果2:断言失败的结果(如下修改)2:参数化断言2.1:添加CSV配置原件2.2:对要测试的内容进行参数化2.3:观察结果树结果与第一章一样都是pass的3:模式匹配规则的介绍3.1:Substring模式匹配规则匹配其中的一段字符…

    2022年10月31日

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号