• java八股文面试[数据库]——数据库锁的种类


    数据库锁的种类

    MySQL数据库由于其自身架构的特点,存在多种数据存储引擎, MySQL中不同的存储引擎支持不同的锁机制。

    • MyISAMMEMORY存储引擎采用的表级锁

    • InnoDB存储引擎既支持行级锁,也支持表级锁默认情况下采用行级锁

    • BDB采用的是页面锁,也支持表级锁

    按照数据操作的类型分

    • 读锁(共享锁):针对同一份数据,多个读操作可以同时进行而不会互相影响。

    • 写锁(排他锁):当前写操作没有完成前,它会阻断其他写锁和读锁。

    按照数据操作的粒度分

    • 表级锁:开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低。

    • 行级锁: 开销大,加锁慢会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。

    • 页面锁:开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般

    按照操作性能可分为乐观锁和悲观锁

    • 乐观锁:一般的实现方式是对记录数据版本进行比对,在数据更新提交的时候才会进行冲突检测,如果发现冲突了,则提示错误信息。

    • 悲观锁:在对一条数据修改的时候,为了避免同时被其他人修改,在修改数据之前先锁定,再修改的控制方式。共享锁和排他锁是悲观锁的不同实现,但都属于悲观锁范畴

    请说一下共享锁和排他锁?

    行级锁分为共享锁和排他锁两种。

    行锁的是mysql锁中粒度最小的一种锁,因为锁的粒度很小,所以发生资源争抢的概率也最小,并发性能最大,但是也会造成死锁,每次加锁和释放锁的开销也会变大。

    使用MySQL行级锁的两个前提

    • 使用 innoDB 引擎

    • 开启事务 (隔离级别为 Repeatable Read)

    InnoDB行锁的类型

    • 共享锁(S):当事务对数据加上共享锁后, 其他用户可以并发读取数据,但任何事务都不能对数据进行修改(获取数据上的排他锁),直到已释放所有共享锁。

    • 排他锁(X):如果事务T对数据A加上排他锁后,则其他事务不能再对数据A加任任何类型的封锁。获准排他锁的事务既能读数据又能修改数据

    加锁的方式

    • InnoDB引擎默认更新语句,update,delete,insert 都会自动给涉及到的数据加上排他锁,select语句默认不会加任何锁类型,如果要加可以使用下面的方式:

    • 加共享锁(S):select * from table_name where ... lock in share mode;

    • 排他锁(x):select * from table_name where ... for update;

    锁兼容

    • 共享锁只能兼容共享锁, 不兼容排它锁

    • 排它锁互斥共享锁和其它排它锁

    image.png

    InnoDB 的行锁是怎么实现的?

    InnoDB行锁是通过对索引数据页上的记录加锁实现的,主要实现算法有 3 种:Record Lock、Gap Lock 和 Next-key Lock。

    • RecordLock锁:锁定单个行记录的锁。(记录锁,RC、RR隔离级别都支持)

    • GapLock锁:间隙锁,锁定索引记录间隙,确保索引记录的间隙不变。(范围锁,RR隔离级别支持)

    • Next-key Lock 锁:记录锁和间隙锁组合,同时锁住数据,并且锁住数据前后范围。(记录锁+范围锁,RR隔离级别支持)

    注意: InnoDB这种行锁实现特点意味着:只有通过索引条件检索数据,InnoDB才使用行级锁,否则,InnoDB将使用表锁

    在RR隔离级别,InnoDB对于记录加锁行为都是先采用Next-Key Lock,但是当SQL操作含有唯一索引时,Innodb会对Next-Key Lock进行优化,降级为RecordLock,仅锁住索引本身而非范围。

    各种操作加锁的特点

    1)select ... from 语句:InnoDB引擎采用MVCC机制实现非阻塞读,所以对于普通的select语句,InnoDB不加锁

    2)select ... from lock in share mode语句:追加了共享锁,InnoDB会使用Next-Key Lock锁进行处理,如果扫描发现唯一索引,可以降级为RecordLock锁。

    3)select ... from for update语句:追加了排他锁,InnoDB会使用Next-Key Lock锁进行处理,如果扫描发现唯一索引,可以降级为RecordLock锁。

    4)update ... where 语句:InnoDB会使用Next-Key Lock锁进行处理,如果扫描发现唯一索引,可以降级为RecordLock锁。

    5)delete ... where 语句:InnoDB会使用Next-Key Lock锁进行处理,如果扫描发现唯一索引,可以降级为RecordLock锁。

    6)insert语句:InnoDB会在将要插入的那一行设置一个排他的RecordLock锁

    下面以“update t1 set name=‘lisi’ where id=10”操作为例,举例子分析下 InnoDB 对不同索引的加锁行为,以RR隔离级别为例。

    1.主键加锁

    加锁行为:仅在id=10的主键索引记录上加X锁。

    image.png

    2.唯一键加锁

    加锁行为:现在唯一索引id上加X锁,然后在id=10的主键索引记录上加X锁。
     

    image.png

    3.非唯一键加锁

    加锁行为:对满足id=10条件的记录主键分别加X锁,然后在(6,c)-(10,b)、(10,b)-(10,d)、(10,d)-(11,f)范围分别加Gap Lock。

    image.png

    4.无索引加锁

    加锁行为:表里所有行和间隙都会加X锁。(当没有索引时,会导致全表锁定,因为InnoDB引擎锁机制基于索引实现的记录锁定)。

    image.png

    知识来源:马士兵教育

  • 相关阅读:
    我们需要工具支持键集分页
    云计算基础知识
    fastadmin搜索时同步进行修改
    【编程题】最小农田浇水费用
    画一个 “月饼” 陪我过中秋,使用 ESP32-C3 制作炫彩月饼(我为嵌入式工程师争取月饼)
    小册上新 | 掌握 SpringBoot 场景整合,成为开发多面手!
    select/poll/epoll
    【数学建模】MATLAB应用实战系列(105)-Logistic回归——二分类(附MATLAB代码)
    数据库中常见的六种约束,有一种MySql不支持,你知道是哪个吗?
    vue3.0中使用echarts,鼠标悬浮无法显示数据框的问题
  • 原文地址:https://blog.csdn.net/u200814342A/article/details/132721362