• mysql的锁介绍


    从共享性上来说,mysql的数据库锁分为:

            共享锁(读锁):lock in share mode;一个事务获取了读锁之后,不排斥其他事务读数据,但排斥其他事务增删改。

            排它锁(写锁):for update;一个事务获取了写锁之后,排斥其他事务增删改查。

    共享锁:

    select * from test_table where age>60 lock in share mode;

    排它锁:

    select * from test_table where age>60 for update

           根据锁的对象的不同,可以将锁分为表锁和行锁。顾名思义,表锁是加在表上的锁,而行锁是加在数据行的上的锁。

    表锁

           mysql的MyISAM引擎就是使用的表锁。MyISAM在执行查询语句(SELECT)前,会自动给涉及的所有表加读锁,在执行更新操作(UPDATE、DELETE、INSERT等)前,会自动给涉及的表加写锁,这个过程并不需要用户干预,因此用户一般不需要直接用LOCK TABLE命令给MyISAM表显式加锁。

            表锁不会出现死锁,发生锁冲突几率高,并发低。所以MyISAM不适合做写为主表的引擎,因为写锁后,其它线程不能做任何操作,大量的更新会使查询很难得到锁,从而造成永远阻塞。

    行锁

           行锁会出现死锁,发生锁冲突几率低,并发高。

           MySQL的InnoDB引擎支持行锁。与Oracle不同,MySQL的行锁是通过索引加载的,也就是说,行锁是加在索引响应的行上的。如果执行的SQL语句没有通过索引方式,则会全表扫描,行锁则无法实现。取而代之的是表锁,此时其它事务无法对当前表进行更新或插入操作。

           也就是说。假设操作A在更新时,由于是通过非主键或索引选中的,升级为为表级锁,这时候A占有锁,这时候操作B则无法对该表进行更新或插入操作,因为它获取不到锁只有当A提交事务后,B才会成功执行。

          在一条select语句后加上for update,则查询到的数据会被加上一条排它锁,其它事务可以读取,但不能进行更新和插入操作。

    行锁的实现需要注意:

    1. 行锁必须有索引才能实现,否则会自动锁全表,那么就不是行锁了。

    2. 两个事务不能锁同一个索引。

    3. insert,delete,update在事务中都会自动默认加上排它锁。

    行锁场景:

    A用户购买物品,service层先查询该物品数量,若数量足够,则进行后续的减操作;这种情况查询的时候应该对该记录进行加锁。否则,B用户在A用户查询后购买前先一步将物品买走,而此时A用户已经进行了物品数量是否足够的判断,则可能会出现物品数量已经不足但却购买成功的情况。为了避免此情况,需要在A用户操作该记录的时候进行for update加锁。

    间隙锁
    当我们用范围条件而不是相等条件检索数据,并请求共享或排他锁时,InnoDB会给符合条件的已有数据记录的索引项加锁;对于键值在条件范围内并不存在的记录,叫做间隙。

    InnoDB也会对这个"间隙"加锁,这种锁机制就是所谓的间隙锁。

    例如:

    1. -- 用户A
    2. update test_table set count=8 where id>2 and id<6
    3. -- 用户B
    4. update test_table set count=10 where id=5;

          这个过程中,假设 id在1-到6之间即便是没有5。这时A操作是占有锁的,且锁对这个不存在的id=5这个数据也加了锁,所以B是无法进行更新的,只能等A提交事务之后,B才能修改。

    行级锁定的优点:
    ·         当在许多线程中访问不同的行时只存在少量锁定冲突。
    ·         回滚时只有少量的更改。
    ·         可以长时间锁定单一的行。

    行级锁定的缺点:
    ·         比页级或表级锁定占用更多的内存。
    ·         当在表的大部分中使用时,比页级或表级锁定速度慢,因为你必须获取更多的锁。
    ·         如果你在大部分数据上经常进行GROUP BY操作或者必须经常扫描整个表,比其它锁定明显慢很多。
    ·         用高级别锁定,通过支持不同的类型锁定,你也可以很容易地调节应用程序,因为其锁成本小于行。

  • 相关阅读:
    【洛谷 P1152】欢乐的跳 题解(枚举+位集合)
    superset支持Kylin4.0.0(兼容处理日期分组功能)
    (十一)Java算法:计数排序(详细图解)
    语音信号处理-基础(三):语音信号分析【连续的“模拟信号”--采样、量化、编码-->离散的“数字信号”】
    容器镜像多架构支持介绍
    Apache DolphinScheduler版本2.0.5分布式集群的安装
    三菱PLC中通过变址寄存器V或Z实现简单跑马灯的程序示例及说明
    Python图像处理中PIL中image.convert()函数
    DTSE Tech Talk 第13期:Serverless凭什么被誉为未来云计算范式?
    亚马逊云科技的AI新引擎,如何助力企业应对“乌卡时代”?
  • 原文地址:https://blog.csdn.net/qq_34484062/article/details/118963346