• 技术文章 >数据库 >mysql教程

    重温MySQL锁机制

    coldplay.xixicoldplay.xixi2021-04-06 10:07:50转载127

    文章目录

    相关免费学习推荐:mysql视频教程

    锁是计算机协调多个线程访问同一共享资源的机制,主要用于解决多线程访问同一共享资源的并发安全问题。
    在这里插入图片描述

    锁分类

    (1)从性能分为:乐观锁和悲观锁
    MySQL中采用版本号控制,JVM中使用CAS

    (2)从数据库操作类型分为:读锁(共享锁)、写锁(排他锁) 【读锁和写锁都属于悲观锁】

    (3)从颗粒度划分为,表锁和行锁

    注意:
    (1)读锁、写锁都属于行级锁,即事务1 对商品A 获取写锁,和事务2对商品B 获取写锁互相不会阻塞的。
    (2)如果sql语句使用了行锁,当SQL未使用索引而使用全表扫描的时候,行级锁会变成表锁。

    (3)锁只有在执行commit或者rollback的时候才会释放,并且所有的锁都是在同一时刻被释放。
    (4)Innodb引擎执行普通的修改、删除sql语句时,会给修改和删除的行加行锁。

    共享锁(读锁,读写互斥,读读互不影响)

    事务A使用共享锁获取了某条(或某些)记录时,事务B可以读取这些记录,可以继续添加共享锁,但是不能修改这些记录(当事务C对这些数据修改或删除时,会进入阻塞状态,直至锁等待超时或者事务A提交)

    # 加锁SELECT ... LOCK IN SHARE MODE# 释放锁commit;rollback;

    排他锁(写锁,独占锁)

    select … for update在对读取的行记录加排他锁,只允许获取到该排他锁的事务修改该行记录,防止其他事务对该行进行修改,就像普通的update语句执行时会加行锁一样。

    # 加排他锁select ... for update //排他锁 # 释放锁commit;rollback;

    共享锁和排他锁的区别

    (1)一旦某个事务获取了排他锁,其他事务就无法再获取排他锁。
    多个事务可以对相同行数据加共享锁。
    (2)给指定行加了共享锁的事务,不一定能修改该行数据,因为其他事务也可能对该行加了共享锁或排他锁; 给指定行加了排他锁的事务,则可以修改加了排他锁的该行数据

    表锁

    使用表级锁定的主要是MyISAM,MEMORY,CSV等一些非事务性存储引擎。
    表锁一般在数据迁移时使用。

    意向锁:意向共享锁和意向排他锁

    某行加共享锁的前提是:该行数据所在表会先获取到意向共享锁。
    某行加排他锁的前提是:该行数据所在表会先获取到意向排他锁。
    注意:意向共享锁和意向排他锁均是表锁,无法手动创建。

    为什么需要加入意向锁

    意向锁是为了告知mysql该表已经存在数据被加锁,而不需要逐行扫描是否加锁,提搞加锁的效率。

    单个表锁定

    lock tables saas.goods read,saas.account write;  // 给saas库中的goods表加读锁,account表加写锁unlock tables;   //解锁

    全局表锁定

    FLUSH TABLES WITH READ LOCK;   // 所有库所有表都被锁定只读unlock tables;         //解锁

    注意: 在客户端和数据库断开连接时,都会隐式的执行unlock tables。如果要让表锁定生效就必须一直保持连接。

    行锁

    行锁升级为表锁(行锁实际是给索引加锁,如果没用索引而全表扫描,则会给全表加锁)

    在这里插入图片描述
    上图中where条件中,虽然template_name建立普通索引,但使用or关键字,导致template_name的索引失效,从而进行了全表扫描,锁定了整张表。

    修改、删除某一行记录,且未提交事务时,该行会一直被行锁锁定

    在这里插入图片描述
    窗口1中删除某一行,但没有提交。窗口2中更新该行会一直处于阻塞中。
    在这里插入图片描述

    记录锁

    间隙锁(Gap Locks)

    经典参考文章

    间隙锁的作用:防止幻读

    间隙锁的目的是为了防止幻读,其主要通过两个方面实现这个目的:
    (1)防止止间隙内有新数据被插入
    (2)防止范围内已存在的数据被更新

    innodb自动使用间隙锁的条件

    (1)数据隔离级别必须为可重复读
    (2)检索条件必须使用索引(没有使用索引的话,mysql会全表扫描,那样会锁定整张表所有的记录,包括不存在的记录,此时其他事务不能修改不能删除不能添加)

    间隙锁锁定的区域

    根据检索条件向左寻找最靠近检索条件的记录值A,作为左区间,向右寻找最靠近检索条件的记录值B作为右区间,即锁定的间隙为(A,B)。下图中,where number=5的话,那么间隙锁的区间范围为[4,11];
    在这里插入图片描述

    session 1:start  transaction ;触发间隙锁的方式1:select  * from news where number=4 for update ;触发间隙锁的方式2:update news set number=3 where number=4; session 2:start  transaction ;insert into news value(2,4);#(阻塞)insert into news value(2,2);#(阻塞)insert into news value(4,4);#(阻塞)insert into news value(4,5);#(阻塞)insert into news value(7,5);#(执行成功)insert into news value(9,5);#(执行成功)insert into news value(11,5);#(执行成功)

    next-key锁【临键锁】

    next-key锁其实包含了记录锁和间隙锁,即锁定一个范围,并且锁定记录本身。InnoDB默认加锁方式是next-key 锁。

    select * from news where number=4 for update ;

    在这里插入图片描述

    next-key锁锁定的范围为间隙锁+记录锁,即区间(2,4),(4,5)加间隙锁,同时number=4的记录加记录锁,即next-key锁的锁定的范围为(2,4],(4,5]。

    记录锁、间隙锁、临间锁的区别

    在这里插入图片描述

    update news  set number=0 where id>15

    sql默认加的是next-key锁。根据上图,next-key锁的区间为(-∞,1],(1,5],(5,9],(9,11],(11,+∞),上面id>15,实际上next-key锁是加在[11,+∞)这个范围内,而不是(15,+∞)这个范围内。注意:需要使用锁的字段必须加索引,因为锁是加在索引上的,没有索引则加的表锁。

    相关免费学习推荐:mysql数据库(视频)

    以上就是重温MySQL锁机制的详细内容,更多请关注php中文网其它相关文章!

    声明:本文转载于:CSDN,如有侵犯,请联系admin@php.cn删除
    专题推荐:MySQL锁机制
    上一篇:MySQL中的人生见证 下一篇:MySQL学习之事务控制
    第15期线上培训班

    相关文章推荐

    • mysql数据库中锁机制的详细介绍• 关于mysql锁机制原理的详细讲解(二)• 如何理解mysql锁机制• 一起彻底搞懂 MySQL 的锁机制

    全部评论我要评论

  • 取消发布评论发送
  • 1/1

    PHP中文网