首页 > 其他分享 >锁的分类(六)

锁的分类(六)

时间:2022-10-01 10:38:50浏览次数:52  
标签:items 分类 修改 where id 1001 quantity

  • ​页级锁​
页锁就是在页的粒度上进行锁定,锁定的数据资源比行锁要多,因为一个页中可以有多个行记录。当我们使用页锁的时候,会出现数据浪费的现象,但这样的浪费最多也就是一个页上的数据行。
页锁的开销介于表锁和行锁之间,会出现死锁。锁定粒度介于表锁和行锁之间,并发度一般。

每个层级的锁数量是有限制的,因为锁会占用内存空间,锁空间的大小是有限的。当某个层级的锁数量超过了这个层级的阈值时,就会进行锁升级。锁升级就是用更大粒度的锁替代多个更小粒度的锁,
比如InnoDB中行锁升级为表锁,这样做的好处是占用的锁空间降低了,但同时数据的并发度也下降了。
  • ​悲观锁​
悲观锁是一种思想,顾名思义,就是很悲观,对数据被其他事务的修改持保守态度,会通过数据库自身的锁机制来实现,从而保证数据操作的排它性。
悲观锁总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会 阻塞 直到它拿到锁(共享资源每次只给一个线程使用,
其它线程阻塞,用完后再把资源转让给其它线程)。比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁,当其他线程想要访问数据时,都需要阻塞挂起。Java中 synchronized 和 ReentrantLock 等独占锁就是悲观锁思想的实现

# 例如在商品秒杀的情景中,避免出现超卖的情况
# 商品信息从查询、生成订单、修改的这个过程,查询到数据后,获取锁,知道修改数据后才释放锁
# 需要将执行的业务放到1个事务中
# 1.查询数据
select quantity from items where id = 1001 for update;
# 2. 生成订单
insert into orders(item_id) values(1001);
# 3. 修改库存
update items set quantity = quantity-num where id = 1001;

# 在使用悲观锁时,必须对要查询的对象使用索引
# 悲观锁对于比较多的业务,开销较大
  • ​乐观锁​
乐观锁认为对同一数据的并发操作不会总发生,属于小概率事件,不用每次都对数据上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,也就是不采用数据库自身的锁机制,
而是通过程序来实现。在程序上,我们可以采用 版本号机制 或者 CAS机制 实现。乐观锁适用于多读的应用类型,这样可以提高吞吐量。在Java中 java.util.concurrent.atomic 包下的
原子变量类就是使用了乐观锁的一种实现方式:CAS实现的

# 实现方式1:版本号机制
# 在表中添加1个字段version,第1个事务第1次读的时候,会拿到这个版本号,最后修改库存的时候,判断版本号是否一致,一致才能修改成功
# 1.查询数据
select quantity from items where id = 1001 for update;
# 2. 生成订单
insert into orders(item_id) values(1001);
# 3. 修改库存
update items set quantity = quantity-num where id = 1001 and version = 1;

# 实现方式2:时间戳机制
# 第1个事务第1次读的时候,会拿到这个时间戳,最后修改库存的时候,判断时间戳是否一致,一致才能修改成功
# 1.查询数据
select quantity from items where id = 1001 for update;
# 2. 生成订单
insert into orders(item_id) values(1001);
# 3. 修改库存
update items set quantity = quantity-num where id = 1001 and updated = 123456;

# 如果数据库是读写分离的表,当主表写入的数据,没有及时同步到从表时,需强制去主表中读数据

# 在使用版本号机制的时候,多个事务第1次读的时候,版本号都是1,当其中1个事务修改后,其他事务则都会修改失败
# 由于每次只有1个事务能够成功,会导致业务感知上有大量的失败操作
# 为了避免以上的现象,可以在最后修改库存时,判断库存不为0则能成功
# 1.查询数据
select quantity from items where id = 1001 for update;
# 2. 生成订单
insert into orders(item_id) values(1001);
# 3. 修改库存
update items set quantity = quantity-num where id = 1001 and quantity-num > 0;
  • 总结
乐观锁适合读操作比较多的场景
悲观锁适合写操作比较多的场景



标签:items,分类,修改,where,id,1001,quantity
From: https://blog.51cto.com/chniny/5728129

相关文章

  • 锁的分类(五)
    ​​临键锁(Next-KeyLocks)​​有时候我们既想锁住某条记录,又想阻止其他事务在该记录前边的间隙插入新记录,所以InnoDB就提出了一种称之为Next-KeyLocks的锁,官方的类......
  • 锁的分类(七)
    ​​显式锁​​#通过特定的语句进行加锁,我们一般称之为显示加锁#显式共享锁select...lockinsharemode#显式排他锁select...forupdate​​隐式锁​​隐式锁是在......
  • 锁的分类(八)
    ​​全局锁​​全局锁就是对整个数据库实例加锁。当你需要让整个库处于只读状态的时候,可以使用这个命令,之后其他线程的以下语句会被阻塞:数据更新语句(数据的增删改)、数据......
  • ALV :汇总,分类汇总(小计),排序,过滤
    货铺QQ群号:834508274下面开始干货部分……ALV标准功能汇总,分类汇总,排序,过滤这些功能除了可以直接使用它的标准功能按钮之外,你也可以在程序里设定,让ALV列表第一次显示出来就......
  • 朴素贝叶斯分类器
    朴素贝叶斯分类器朴素贝叶斯算法:它是一种基于贝叶斯定理的监督机器学习算法。它是一种用于各种分类任务的概率机器学习算法。在我们深入探讨这个话题之前,我们首先要了解......
  • SARscape5.6.2形变结果分类工具介绍
    SARscape5.6.2版本干涉叠加模块新增时序分类工具,可对时序InSAR进行高级后处理和分析。该工具通过现象特征和参数分析对位移时间序列进行自动分类。可使用外部气象数据(雨、......
  • 网络编程-IP地址的分类
    网络编程-IP地址的分类网络中有多台计算机,它们必须通过某种标识来区分每一台机器,这个用于区分的标识这就是IP地址;IP地址由4个数字组成,形如“192.168.1.1”。(其实是4个字......
  • 18个面向初学者的经典开源计算机视觉项目-图像分类篇Inception(三)
    在研究这篇文章时,有一点很清楚。2014年是发展真正流行的图像分类预训练模型的标志性一年。尽管上述VGG-16在当年的ILSVRC中排名第二,但排名第一的不是别人,正是谷歌——通过它......
  • 深度学习:文本分类模型中的“蒸”功夫
    作者:Xingzhe.AI来自:行者AI 前言2018年Bert的横空出世给自然语言处理带来了巨大的突破,Bert及其衍生模型在多个文本处理下游任务中达到了SOTA的结果。但是这样的提升是......
  • EXCEL如何实现分类
    目的:根据第二列的不同计划线分类来筛选出第一列的料号第一步:选中两列第二步:点击插入,选择"数据透视表"效果图图一:两列都选择行图二:一列设置为筛选器,一列设置为......