首页 > 数据库 >MySql锁知识记录积累(一)

MySql锁知识记录积累(一)

时间:2023-06-08 16:36:01浏览次数:60  
标签:积累 事务 记录 间隙 查询 临键 索引 MySql

1.关于脏读、幻读和不可重复读

脏读:一个事务A读取到了另一个事务B未提交的数据,叫做脏读 不可重复读:事务A被事务B干扰到了!在事务A范围内,两个相同的查询,读取同一条记录,却反返回了不同的结果,即不可重复读 幻读:事务A查询一个范围内的结果集,另一个并发事务B往这个范围中插入/删除了数据,并提交。然后事务A再次查询,结果查询到了不同的结果,这就是幻读。

2.事务隔离级别

MySql锁知识记录积累(一)_共享锁

在并发情况下,读未提交的事务隔离级别下,是不加锁的会存在 脏读、幻读和不可重复读的问题

3.InnoDB七种锁介绍

MySql锁知识记录积累(一)_记录锁_02

3.1共享/排他锁

InnoDB存储引擎实现了两种标准的行级锁:共享锁-Share(简称S锁)、排他锁(简称X锁)

  • 共享锁:在事务想要读取一条记录的时候,需要先获取该记录的共享锁。
  • 排他锁:在事务想要修改一条记录的时候,需要先获取该记录的排他锁。

共享锁存在的意义

  • 存在若干个事务想要读取一条记录,需要先获得该记录的共享锁,是为了避免该记录被其他事务所修改。

排他锁存在的意义

  • 当一个事务想要修改一条记录,需要先获得该记录的排他锁,此时其他事务无法读取该数据,直到排他锁释放。

3.2意向锁

意向锁解释:不与行级别锁冲突的表级锁。未来某个时刻,事务可能需要加共享锁或者排他锁的时候,先提前声明一个意向。是一个表级别的锁。

为什么需要意向锁?

  • 假设一个事务A获取了表中一行数据的排他锁
  • 此时事务B想要读取全表数据,需要对整张表加共享锁,因此需要保证表中不存在排他锁
  • 问题来了
  • 事务B想要判断表中是否存在排他锁,难道要全表遍历?
  • 为了解决该问题,因此有了意向锁

实际运行过程

  • 当一个事务A想要对表中的数据进行 读取/修改 的时候,需要向增加一个全表级别的 意向共享锁/意向排他锁
  • 此时其他事务想要对全表中的数据进行修改,就会发现表中存在全表级别的 意向锁,从而不需要避免了全表找锁:::

3.3记录锁

记录锁是粒度最小的锁,仅仅锁住一行。记录锁加在索引上,如果一张表中没有索引,InnoDB会隐式创建一个索引,并用该索引加记录锁。 记录锁关键词lock_mode X locks rec but not gap

3.4间隙锁(Gap Lock)

间隙锁是一种加在两个索引之间的锁,或者加在第一个索引之前,最后一个索引之后的间隙,锁住的是一个区间。lock_mode X locks gap before rec为了解决幻读问题 间隙锁左右都是开区间

当SQL语句查询范围数据的时候,会对查询的范围区间加上间隙锁。此时,其他事务无法在加上了间隙锁的范围区间内插入新的数据,避免了幻读。

间隙锁仅在 RR 隔离级别下出现

PS:在RR(可重复读)的隔离级别下,普通查询是快照读,不会发生幻读。如果使用“当前读”(即:for update)才有可能发生幻读

3.5临键锁(Next-Key Lock)

临键锁:锁住索引本身和索引之前的间隙,左开右闭区间

临键锁的加锁场景:当SQL使用非唯一索引的条件进行数据检索的时候,会给匹配到的行加上临键锁

如下表数据

id

name

sex

age

1

kk


10

2

lily


20

3

LiNa


30

4

QQ


40

5

HH


60

6

ZZ


80

7

NN


100

在该表的 age 列增加普通非空唯一索引。那么临键锁可能的区间为

  • (负无穷, 10] (10, 20] (20, 30] (30, 40] (40, 60] (60, 80] (80, 100] (100, 正无穷)

临键锁的具体产生场景:

  • 如果是等值查询且记录存在,即 begin; select * from xxx where age = 30 for update;
  • 此时仅仅会锁住 age=30 这一行记录
  • 等值查询且记录不存在,即 begin; select * from xxx where agen = 45 for update;
  • 此时会锁住 [40, 60] 的间隙 若 40 <= age <= 60 则会插入失败
  • 范围查询 select * from where age >= 25 and age <=35
  • 首先查询 age = 25 的记录判断是否存在,不存在 临键锁 (20, 30]
  • 同上 age = 35 不存在,加锁 (30, 40]
  • 总加速范围 Next-Key Lock (20, 40]

加锁规律总结

唯一索引等值查询

  • 查询记录存在,记录锁 Record Lock
  • 不存在,间隙锁 Gap Lock

唯一索引范围查询

  • 间隙锁或记录锁

非 唯一索引等值查询

  • 记录存在 Next-key Lock 临键锁 和 间隙锁 Gap Lock
  • 记录不存在 间隙锁 Gap Lock

非 唯一索引范围查询

  • Next-Key Lock 临键锁

3.6插入意向锁

在执行插入一行记录操作之前设置的一种间隙锁。 解决的问题:

  • 多个事务,在同一个索引范围区间内,执行插入操作的时候,如果插入的数据不冲突,就不会阻塞彼此。
  • 假设 数据范围 [7, 100] 多个时候在范围区间内插入不同数据的时候不会阻塞

3.7自增锁

特殊的表级别锁,针对 AUTO_INCREMENT

  • 如果表中新增一条数据,就会持有自增锁
  • 此时其他事务向表中插入数据必须等待自增锁释放,以便保证连续的主键值

标签:积累,事务,记录,间隙,查询,临键,索引,MySql
From: https://blog.51cto.com/u_16079703/6441260

相关文章

  • mysql备份
    https://www.manongdao.com/article-1640390.html 备份的类型1、根据是否需要数据库离线(1)冷备:需要关mysql服务,请写请求均不允许(2)温备:服务在线,但仅支持读请求。(3)热备:备份的同时,业务不受影响。mysql中进行不同方式的备份还需要考虑存储引擎是否支持 MyISAM InnoDB......
  • CF1338 Div.1 做题记录
    ACF题面假定用到的最大的数是\(x\),那么一个数最大可以增大\(2^x-1\)。题目只要求不降,所以求出将\(a_i<a_{i-1}\)变成\(a_i=a_{i-1}\)时需要增大的最大值。求出这个数的二进制位数即可。点击查看代码#include<bits/stdc++.h>#defineullunsignedlonglong#definell......
  • Kettle连接MySQL报错:Driver class 'org.gjt.mm.mysql.Driver' could not be found, ma
    在Windows系统里面安装kettle后打算连接MySQL的时候突然报错错误连接数据库[wanghui]:org.pentaho.di.core.exception.KettleDatabaseException:ErroroccurredwhiletryingtoconnecttothedatabaseDriverclass'org.gjt.mm.mysql.Driver'couldnotbefound,mak......
  • redis应用场景--记录文章,图文,或者视频的浏览次数
    在阅读博客文章时,你可以看到一篇文章被阅读的次数,如果使用mysql,那么在设计article表时,就必须设置一个view_count字段来记录这篇文章被阅读的次数。但这种方式相比于使用redis,并不是一种好的办法,原因在于,每次更新view_count字段的值都是一个比较费力的过程。首先,程序需要根据文......
  • 【MySQL】二进制安装MySQL
    一、基于Ubuntu二进制安装MySQL8.0(5.7+适用)1、创建用户[root@Node-Ubuntu1804-20:~]#groupaddmysql[root@Node-Ubuntu1804-20:~]#useradd-r-gmysql-s/usr/sbin/nologinmysql 2、创建目录[root@Node-Ubuntu1804-20:~]#mkdir/data/mysql-p[root@Node-Ubunt......
  • mysql xplugin mysqlx
    https://dev.mysql.com/doc/refman/8.0/en/x-plugin-options-system-variables.html  Bydefault,foritsXpluginfeatures,MySQLlistensonport33060,boundtoallIPaddresses.See manualsectiononXpluginoptionsandsystemvariables (indicatingdefau......
  • MySQL索引的数据结构
    一:索引概述MySQL官方对索引的定义为:索引(Index)是帮助MySQL高效获取数据的数据结构。索引的本质:索引是数据结构。可以简单理解为“排好序的快速查找数据结构”,满足特定查找算法。这些数据结构以某种方式指向数据,这样就可以在这些数据结构的基础上实现高级查找算法。1:索引优缺点......
  • C#使用webview2摸拟网页提交的一些记录
    想要在C#使用中webview2,最好使用VS2019及以上版本,最低支持.net4.5版本,所以在win7系统上就可以进行开发了ReoGrid是一个类Excel的控件,非常好用,两者搭在一起,可以实现一些自动化的输入工作,非常的方便,Excel的内容可以直接粘贴到这个控件里面 下面说说使用过程中遇到的问题:1、安......
  • mysql8.0设置时区
    在MySQL8.0中,可以使用以下命令查看当前数据库系统的时区设置:SELECT@@global.time_zone;该命令将返回一个字符串,表示当前数据库系统的时区设置。例如,返回如下结果:+--------------------+|@@global.time_zone|+--------------------+|SYSTEM|+------......
  • mysql常见的时间查询语句
    mysql数据库要按当天、昨天、前七日、近三十天、季度、年查询查询今天select*from表名whereto_days(时间字段名)=to_days(now());   查询昨天SELECT*FROM表名WHERETO_DAYS(NOW())-TO_DAYS(`时间字段名`)=1 查询7天 sql语句SELECT*FROM表名whereDATE_SUB(CU......