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

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

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

场景

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

第一种方法 悲观锁

悲观并发控制(又名 “悲观锁”,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))
{
//下单逻辑...
}

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

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

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

(0)
上一篇 2022年2月20日 下午2:00
下一篇 2022年2月20日 下午3:00


相关推荐

  • ntp时间同步协议_ntp服务器搭建

    ntp时间同步协议_ntp服务器搭建一、简介1.作用NTP是从时间协议(TimeProtocol)和ICMP时间戳报文(ICMPTimeStampMessage)演变而来,在准确性和健壮性方面进行了特殊的设计,理论上精度可达十亿分之一秒。NTP协议应用于分布式时间服务器和客户端之间,实现客户端和服务器的时间同步,从而使网络内所有设备的时钟基本保持一致。NTP协议是基于UDP进行传输的,使用端口号为123。2.特征NTP提供了准…

    2022年10月11日
    2
  • windows下搭建tracker服务器

    windows下搭建tracker服务器RT,需要下载工具下载,解压,得到一个BitCometTracker_0.5[做服务器tracker]的文件夹,打开“BitCometTracker_0.5”文件夹,双击运行“BitCometTracker”打开软件之后,状态是停止的的状态,需要点击“run”这样就行了,如果需要修改配置端口,需要点击“config”架设好后,您的tracker服务器…

    2022年6月16日
    85
  • Pycharm安装包(类库)的方法总结及解决包下载慢的问题

    Pycharm安装包(类库)的方法总结及解决包下载慢的问题1.在编译文本里面当你引用的包没有下载时,pycharm会自动用红色的灯泡来提示,这时,你直接点击红色灯泡,会出现一个下拉框,选择下载包的哪一项,pycharm就会自动下载,你没有安装的包。2.在有建立好的一个工程下:file->Settings->Project:(你已经建立好的工程名字)->在这里面有两个选项,选项一:ProjectInterpreter(工程解释…

    2022年5月17日
    40
  • 交换排序之高速排序[通俗易懂]

    交换排序之高速排序

    2022年1月19日
    54
  • srsLTE测试SDR频偏[通俗易懂]

    srsLTE测试SDR频偏[通俗易懂]1、在Android手机上使用网络信号大师确定当前连接基站的EARFCN。2、修改srsue的ue.conf中earfcn参数为手机连接的基站。3、启动srsue尝试接入,如果收不到基站或接入失败,可以调节ue.conf中的频偏(freq_offset)参数,可以从修改-15000到15000(可以5000为步进调节)不停重复尝试接入。4、能成功接入基站后,FoundCell信息中会有CFO参数,此参数即为频偏,然后再根据此值调试频偏值,频偏=频偏+CFO,比如CFO为-5.5k,频偏=频偏-

    2026年4月15日
    4
  • 动态拼接update sql语句

    动态拼接update sql语句WriteDataSou StringtableN List lt String gt keyList List lt String gt valueList StringBuilde newStringBui sb append UPD

    2026年3月19日
    3

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

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