• MySQL8.0优化 - 锁 - 按加锁的方式划分:显示锁、隐式锁



    学习资料

    【MySQL数据库教程天花板,mysql安装到mysql高级,强!硬!-哔哩哔哩】
    【阿里巴巴Java开发手册】https://www.w3cschool.cn/alibaba_java

    锁的不同角度分类

    锁的分类图如下

    在这里插入图片描述

    按加锁的方式划分:显示锁、隐式锁

    隐式锁

    一个事务在执行INSERT操作时,如果即将插入的间隙已经被其他事务加了gap锁,那么本次INSERT操作会阻塞,并且当前事务会在该间隙上加一个插入意向锁,否则一般情况下INSERT操作时不加锁的。那如果一个事务首先插入了一条记录(此时并没有在内存生产该记录关联的锁结构),然后另一个事务:

    立即使用SELECT ... LOCK IN SHARE MODE语句读取这条记录,也就是要获取这条记录的S锁,或者使用SELECT ... FOR UPDATE语句读取这条记录,也就是获取这条记录的X锁,怎么办?
    如果允许这种情况的发生,那么可能产生脏读问题。
    立即修改这条记录,也就是要获取这条记录的X锁,怎么办?
    如果允许这种情况的发生,那么可能产生脏写问题。
    这时候我们前边提过的事务id又要起作用了。我们把聚簇索引和二级索引中的记录分开看一下:

    情景一:对于聚簇索引记录来说,有一个trx_id隐藏列,该隐藏列记录着最后改动该记录的事务id。那么如果当前事务中新插入一条聚簇索引记录后,该记录的trx_id隐藏列代表的就是当前事务的事务id,如果其他事务此时想对该记录添加S锁或者X锁时,首先会看一下该记录的trx_id隐藏列代表的事务是否是当前的活跃事务,如果是的话,那么就帮助当前事务创建一个X锁(也就是为当前事务创建一个锁结构,is_waiting属性false),然后自己进入等待状态(也就是为自己也创建一个锁结构,is_waiting属性是true)。

    情景二:对于二级索引记录来说,本身并没有trx_id隐藏列,但是在二级索引页面的Page Header部分有一个PAGE_MAX_TRX_ID属性,该属性代表对该页面做改动的最大的事务id,如果PAGE_MAX_TRX_ID属性值小于当前最小的活跃事务id,那么说明对该页面做修改的事务都已经提交了,否则就需要在页面中定位到对应的二级索引记录,然后回表找到它对应的聚簇索引记录,然后再重复情景一的做法。

    即:一个事务对新插入的记录可以不显式的加锁(生成一个锁结构),但是由于事务id的存在,相当于加了一个隐式锁。别的事务在对这条记录加S锁或者X锁时,由于隐式锁的存在,会先帮助当前事务生成一个锁结构,然后自己再生成一个锁结构后进入等待状态。隐式锁是一种延迟加锁的机制,从而来减少加锁的数量。

    隐式锁在实际内存对象中并不含有这个锁信息。只有当产生锁等待时,隐式锁转化为显示锁。

    显式锁

    通过特定的语句进行加锁,我们一般称之为显示加锁,例如:
    显示加共享锁:
    select .... lock in share mode
    显示加排它锁:
    select .... for update

  • 相关阅读:
    UDP和TCP的区别
    gRPC之gRPC认证
    VAE原理及代码实现
    集合的进阶学习
    亚马逊鲲鹏AI智能养号好用吗?怎么使用的?
    客户听不进去,很强势,太难沟通了,怎么办?
    云计算未来展望:边缘计算、量子计算与AI
    (附源码)springboot毕业生弃置物品交易系统 毕业设计 231151
    Centos7 Shell编程之函数、消息的发送与接收
    批量检测url是否存在cdn—高准确率
  • 原文地址:https://blog.csdn.net/ChinaYangJu/article/details/127939230