图解MySQL中乐观锁扣减库存原理 新资讯
这篇文章主要为大家详细介绍了MySQL中乐观锁扣减库存原理的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起了解一下
脚本之家 2023-04-14 05:48:58
在电商系统中扣减库存是一步非常关键的操作,例如秒杀系统中一定要防止超卖情况出现,如果商家设置了100件库存但是最后卖出1000件,这样就会产生资金损失。在扣减库存时一般使用如下语句:
udpate goods set stock = stock - #{acquire} where sku_id = #{skuId} and stock - #{acquire} >= 0
这条语句可以保护库存资源防止超卖,我们不妨分析这条语句为什么生效。本文使用MySQL Innodb引擎进行演示,隔离级别为可重复读。
【资料图】
共享锁(share Lock)又被称为读锁,实现共享锁语句如下:
select lock in share mode
排它锁(exclusive Lock)又被称为写锁,实现排它锁语句如下:
select for update update delete insert
共享锁与排它锁兼容关系如下表:
我们通过实例分析上述兼容关系,首先建一张测试表并写入测试数据:
CREATE TABLE `test_account` ( `id` bigint(20) NOT NULL, `name` varchar(20) DEFAULT NULL, `account` bigint(20) DEFAULT NULL, `version` bigint(20) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; insert into `test_account`(`id`,`name`,`account`,`version`) values (1,"A",100,1); insert into `test_account`(`id`,`name`,`account`,`version`) values (2,"B",200,1); insert into `test_account`(`id`,`name`,`account`,`version`) values (3,"C",300,1);
(1) 读读兼容
共享锁与共享锁之间兼容,在如下实例中session1在t3时刻,session2在t4时刻执行查询均可以获取预期结果:
(2) 读写互斥
共享锁与排它锁之间互斥,在如下实例中session1在t3时刻加共享锁,可以正确读取结果,但是session2在t4时刻尝试加排它锁,但是此时锁被session1占有,session2需要等待,当session1长时间不释放锁时,session2抛出锁超时异常:
(3) 写写互斥
排它锁与排它锁之间互斥,在如下实例中session1在t3时刻加排它锁,可以正确读取结果,但是session2在t4时刻尝试加排它锁,但是此时锁被session1占有,session2需要等待,当session1长时间不释放锁时,session2抛出锁超时异常:
MySQL Innodb存储引擎实现基于多版本并发控制协议MVCC,在MVCC并发控制中读操作可以分成快照读与当前读。
快照读不需要加锁,读取的是记录可见版本,有可能是历史版本。可以类比订单快照,用户下单之后商品价格发生了变化,但是订单快照不会改变。实现当前读语句如下:
select
当前读需要加锁,读取的是记录最新版本,加锁保证了在读取时,当前记录不会被其它事务修改。实现当前读语句如下:
select lock in share mode select for update update delete insert
我们通过一个实例分析快照读和当前读,session2在t4时刻修改记录并在t5时刻提交,session1在t6时刻进行了快照读,读取的是本事务开始时结果100,在t7时刻进行了当前读,读取的是记录最新版本结果101:
当前读流程是怎么样的呢?我们以update为例进行分析当前读流程:
第一次程序实例发出当前读请求,存储引擎返回满足where条件的第一条记录并加锁,程序实例再发出更新请求,存储引起操作完成响应成功。依次执行直到所有满足where条件记录执行完成为止。
这里我们做一些引申,RR级别提供了两种机制避免幻读问题:第一种方式是快照读,读取的是当前事务开启时的快照。第二种方式针对当前读,防止幻读依赖Next-Key Lock机制。
我们通过一个问题将上述知识整合起来:有两个线程在同一时刻执行如下语句,请问id=1这条记录account值会不会成功扣减两次?
update test_account set account = account - 100, version = version + 1 where id = 1 and version = 1
上述语句使用了乐观锁,我们知道乐观锁就是对资源进行保护的,所以答案是不会扣减两次,但是不能就此止步,需要结合第一章节知识进行进一步分析:
t2时刻session1和session2同时执行update操作,由于update会加排它锁,所以两者只能有一个成功:session1成功,session2阻塞等待排它锁释放。
t3时刻session1提交事务释放排它锁,此时session2获取到锁进行当前读,但是此时id=1记录version值已经变成了2,执行语句已经查询不到待更新数据,所以没有记录发生更新。
如果理解了第二章节乐观锁原理,那么扣减库存原理已经显而易见,我们假设商品只剩下1件库存,如果两个线程同时执行扣减库存,会发生超卖的情况吗?
t2时刻session1和session2同时执行updatek扣减库存,由于update会加排它锁,所以两者只能有一个成功:session1成功,session2阻塞等待排它锁释放。
t3时刻session1提交事务释放排它锁,此时session2获取到锁进行当前读,但是此时商品1库存已经变为0,已经不满足(where stock - 1 >= 0)条件,执行语句已经查询不到待更新数据,所以没有记录发生更新。
以上就是图解MySQL中乐观锁扣减库存原理的详细内容,更多关于MySQL乐观锁扣减库存的资料请关注脚本之家其它相关文章!
这篇文章主要为大家详细介绍了MySQL中乐观锁扣减库存原理的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起了解一下
1、前言每次去餐厅点菜总少不了糖醋排骨,吃过很多种,自己就琢磨着做了几次,这次加糖比较多接近上海那边的口味。2、做法上比
1、上网搜索并下载应用程序“WINRAR”。2、下载完成后直接进行安装,其安装过程很简单。3、 2、直接在需要打开的压
一、前言最近人工智能、深度学习又火了,我感觉还是有必要研究一下。三年前浅学了一下原理没深入研究框架,三年后感觉各种框架都成熟了,现成
据《每日邮报》报道,多家英超俱乐部都在关注费耶诺德主帅斯洛特(ArneSlot),这其中包括了热刺、水晶宫和西汉姆联。最近解雇孔蒂和维埃拉后
2023年特种油墨板块股票一览(4月13日),南方财富网为您整理的2023年特种油墨概念股,供大家参考。松井股份:公司是一家以3C行业中的高端消费
爱电影·爱生活图片来源网络各盟市电影主管部门,中国银联内蒙古分公司,内蒙古电影发行放映协会,全区各院线公司、电影院:为进一步促进电影
广东地铁上的一个女孩火了!这次的爆火给女孩带来的无穷的伤害!以“3号线地铁姑娘脱衣服事件”命名的故事被广泛传播一个无辜的女孩在始作俑者
个股年报一般在次年的1月份发。年报是上市公司1年的经营情况,年报可作为投资的参考指标。业绩是决定股票涨跌其中有一个原因,短期会让个股造
截至2023年4月13日收盘,新凤鸣(603225)报收于11 02元,下跌1 43%,换手率0 59%,成交量9 04万手,成交额9955 5万元。
当地时间4月12日,电子烟制造商JuulLabs同意支付超10亿美元,以了结美国45个州对Juul非法向未成年人销售其成瘾产品的指控。各州指控Juul错误地
国新办于今天(4月12日)下午举行“权威部门话开局”系列主题新闻发布会。据介绍,能源行业将全面推进能源高质量发展。在加快推进能源消费方式
起源于新疆的烘焙企业香颂国际近期因在纳斯达克上市受到关注,但未逃脱破发命运。截至北京时间4月13日,香颂国际盘前价格为1 2美元 股,较4美
球天下4月13日讯在刚刚结束的欧冠1 4决赛首回合比赛中,“蓝月军团”曼城坐镇伊蒂哈德球场3-0完胜德甲豪门拜仁慕尼黑,哈兰德传射建功。本场比
番禺区及荔湾区各有一宅地出让,番禺区地块进入摇号环节,荔湾区地块由广东建工联合体底价拿下。